ocp
o代表open ,c代表closed
在软件开发过程中应当对扩展开放,对修改关闭。也就是说,如果在进行功能扩展的时候,添加额外的类是没问题的,但因为功能扩展而修改之前运行正常的程序,这是忌讳的,不被允许的。因为一旦修改之前运行正常的程序,就会导致项目整体要进行全方位的重新测试。
dip
依赖倒置原则(dependence inversion principle),简称dip,主要倡导面向抽象编程,面向接口编程,不要面向具体编程,
让上层不再依赖下层,下面改动了,上面的代码不会受到牵连。
怎么做到呢?当然是用接口。
这样可以大大降低程序的耦合度,耦合度低了,扩展力就强了,同时代码复用性也会增强。(软件七大开发原则都是在为解耦合服务)
控制反转ioc(invension of control)
控制反转是一种新型的设计模式
交出的权力
new对象的权力
对象之间的关系(到底用的是哪一个实现类)
spring
是实现类ioc的容器。
ioc是思想,di是实现。通过di实现bean管理(有bean对象的创建和bean与bean之间关系的维护)。
di(依赖注入)有set注入和构造注入
依赖注入之set注入
这里最后一行的理解,先能找到是哪一个set方法,再找到形参对应的实际参数到底在哪里。
外部 bean
- 在 spring 配置文件中单独定义
- 可以被多个其他 bean 引用
- 有自己独立的 id/名称
<!-- 外部 bean 定义 --> <bean id="address" class="com.example.address"> <property name="city" value="beijing"/> </bean> <!-- 引用外部 bean --> <bean id="employee" class="com.example.employee"> <property name="address" ref="address"/> </bean>
内部 bean
- 直接在引用它的 bean 内部定义
- 只能被当前 bean 使用
- 没有独立的 id/名称
<bean id="employee" class="com.example.employee"> <property name="address"> <!-- 内部 bean 定义 --> <bean class="com.example.address"> <property name="city" value="beijing"/> </bean> </property> </bean>
作用范围不同
特性 | 外部 bean | 内部 bean |
---|---|---|
作用域 | 全局可用 | 仅限当前 bean 内部使用 |
生命周期 | 由容器管理 | 随外部 bean 创建和销毁 |
是否可重用 | 是,可被多个 bean 引用 | 否,只能被当前 bean 使用 |
构造注入
set注入在创建对象之后,而构造注入在创建对象的时候就注入了。
xml解析+工厂模式+反射机制
ioc思想的一种具体实现是依赖注入di
八大框架
两个核心模块 ioc aop
aop
orm(object-relational mapping,对象关系映射) 是一种编程技术,用于在 面向对象编程语言(如 java、python)中的对象与 关系型数据库(如 mysql、postgresql)的表之间建立映射关系,从而让开发者能够以操作对象的方式间接操作数据库,无需直接编写复杂的 sql 语句。
spring的非侵入体现在哪里
spring框架的非侵入式(non-invasive)设计是其核心哲学之一,指的是它不会强制要求你的代码必须依赖spring特定的类或接口,而是允许你以原生方式编写业务逻辑,仅在需要时通过配置或注解引入spring的能力。以下是具体分析:
1. 什么是“非侵入式”?
传统框架的侵入性:
例如早期的ejb 2.x,要求业务类必须继承特定父类或实现指定接口(如sessionbean
),代码与框架深度耦合。
// ejb 2.x的侵入式写法(必须实现框架接口) public class userservice implements sessionbean { // 必须实现框架方法 public void ejbactivate() {} // 业务逻辑... }
spring的非侵入性:
你的类可以是纯pojo(plain old java object),无需继承或实现spring的类/接口。
// spring中的pojo(完全独立于框架) public class userservice { public void adduser(string name) { // 纯业务逻辑 } }
2. spring如何实现非侵入式?
(1)依赖注入(di)通过配置/注解实现
不需要实现特定接口,只需通过@autowired
或xml配置即可注入依赖:
@service public class orderservice { @autowired // 通过注解注入,不依赖spring接口 private paymentservice paymentservice; }
(2)aop通过代理模式实现
切面编程通过动态代理(jdk/cglib)增强功能,业务类无需感知:
@transactional // 只需添加注解,不改变类继承结构 public void updateorder(order order) { // 业务代码 }
(3)模板模式消除样板代码
如jdbctemplate
封装了jdbc的繁琐操作,但你的dao类无需继承任何spring类:
@repository public class userdao { @autowired private jdbctemplate jdbctemplate; // 直接使用,无需实现spring接口 }
3. 非侵入式的核心优势
特性 | 侵入式框架 | spring(非侵入式) |
---|---|---|
代码耦合度 | 高(依赖框架父类/接口) | 低(pojo + 配置/注解) |
可测试性 | 需依赖框架环境测试 | 可直接单元测试(无框架依赖) |
迁移成本 | 重构代价高 | 轻松切换其他框架或去spring化 |
灵活性 | 受框架设计限制 | 自由选择技术组合 |
4. 对比其他框架
侵入式框架示例:
- struts 1.x(action需继承
actionform
) - ejb 2.x(需实现
sessionbean
)
- struts 1.x(action需继承
spring的非侵入式体现:
- 你的
userservice
可以同时用于spring、非spring环境,甚至移植到quarkus/micronaut。 - 仅需修改配置(如从xml换为
@bean
),无需改动业务代码。
- 你的
总结
spring通过依赖注入、aop代理、模板模式等设计,将框架能力以无感知方式注入到业务代码中,使得开发者可以:
✅ 用原生java对象编写核心逻辑
✅ 按需选择spring功能(而非强制)
✅ 轻松迁移或与其他框架集成
这种设计正是spring能成为java生态基石的关键原因之一。
到此这篇关于spring 依赖注入、aop代理全方面解析的文章就介绍到这了,更多相关spring 依赖注入aop内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论