个人觉得这是一个涵盖了spring重要的知识点的,篇幅不算太长的文章,知识点比较全面,可以作为快餐式阅读。
目录
1. 一张图来说明spring
2.spring 的主要内容有 IOC,就是控制反转,将对象的创建权交给容器去管。
3.DI 依赖注入
4.工厂类
5.bean的生命周期(不重要)
5. IOC如何使用注解来开发
6. spring 的IOC的注解详解
7.注解开发和XML开发的对比:
8. Spring中的另外一个重点:AOP
9.AOP相关术语与应用
10. spring中的通知类型
spring 相关的重要图
1. 一张图来说明spring说spring是属于一站式框架,从这张图最能体现:
- 1.第一部分解决的是数据访问的问题
- 2.第二部分解决web问题
- 3.aop是面向切面
- 4.spring的核心,IOC 。比方说spring 控制了类,通过bean
- 5.单元测试
问题来了,为啥要控制反转呢,好好的new对象不行吗?IOC解决了什么问题?
下边说一下IOC底层原理,和为什么这样设计:
传统是这样做的:
可以看到是,技术的发展是随着业务的需求的,IOC的出现的真正的目的也是解耦合,方便我们对代码的维护,当我们一定要修改代码时,如何简单,就如何发展。整合软件的行业发展也是如此。
那么IOC的底层原理又是什么呢?一步一步分析:先将通过配置文件的开发方式
- 首先是配置文件里边的内容,先不解释
- 4. spring就是这样做的,通过判断配置文件里边的 id 的内容,来决定创建哪个对象的实例,通过class 后边的类名,来反射创建对象。
总结,spring 就是通过 配置文件,工厂模式,反射,来实现控制反转的。从而实现了解耦合。
3.DI 依赖注入上边说到,IOC是将 类的对象的创建交给容器。考虑一下这样的场景:万一 一个类 需要依赖另外一个类呢?
具体依赖表示如图:
上图是依赖另外一个类,也有可能要依赖一个属性。只要这个类交给容器来管,那就可以在配置文件中去配置。
上图红框,就叫依赖注入。
所以区分一下DI 和 IOC DI是容器在管理类的时候,把需要的属性设置进来。
给Bean中的属性设置值有三种方法:
spring支持前两种:
构造方法:
set方法
set方法对于对象类型的注入
命名空间的方式注入:
4.工厂类
- 老版本工厂类,BeanFactory
- 新版本工厂类,ApplicationFactory
新版本是我们现在使用的,新版本继承了老版本,有更强大的功能。最大的区别在于,老版本的类的实例是在调用getBean的时候创建,新本的是在加载配置文件的时候创建类的实例。
新版本的工厂类有两个实现类:
红色标记的是我们常用的。
5.bean的生命周期(不重要)配置文件 标签里边的name 和 id 的区别
交给容器管理的类,是默认是单例的。
其实bean的生命周期就是类的生命周期。
在标签里边还有两个属性:一个是初始化,一个是销毁时。
6.Bean 的作用范围
bean标签还有一个属性:scope ,它的取值有以下几个,分别表示不同的作用域范围。
action是多例的,所以一定要开启多例。默认是多例的。
5. IOC如何使用注解来开发- 第一步先引入下边的红框内容,才能再xml文件中使用相应标签不报错。
- 第二部呢就在xml文件中开启扫描,只有让spring容器知道要去扫描,它才会去扫描。
- 第三部就是在想要交给spring容器管理的类上加上注解:
- 第四部,如果先要给属性赋值,也就是DI:那也很简单:
6. spring 的IOC的注解详解
和标签有等同效果的注解: 将这个类交给spring去管理,添加上这个注解以后,spring容器就能发现这个类了。
- @Component:组件
- @Component 有一下三种衍生注解,为什么要衍生呢?从名字上就可以很容易看出来,就是为了分层更加清晰。效果相同。
- 从@Component 衍生的 :@Controller
- 从@Component 衍生的 :@Service
- 从@Component 衍生的 :@Repository
依赖注入的注解:
- 注入普通属性:直接在属性上边 @Value("")
- 注入对象类型的属性:@Autowired
- 想要按照名称对 对象注入再加上:@Qualifier(value="name")
- 想要注入对象类型,我们在开发过程中往往这样来做:@Resource(name="name")
标签上的其它的注解:生命周期相关的注解(了解就好,不常用)
- @PostConstruct :加在方法上,初始化。
- @PreDestroy 就是销毁。
标签上的其它的注解:bean的作用范围(这个常用)
- @Scope 默认是单例的
- @Scope(singleton):单例的
- @Scope(prototype):多例的
- @Scope(request):
- @Scope(session):
- @Scope(globalsession)
7.注解开发和XML开发的对比:
关于二者的使用,完全可以根据开发来选择,并且不是固定的,虽然使用注解,这改动起来可能会比较麻烦,但是从长期的经验来看,在开发中,并不会频繁的改动。所以完全可以两者结合。
如果是想要混合使用开发的话,一般是属性注入使用注解,类交给spring管理的这个工作仍然使用XML来配置。这不需要包扫描 了,但是需要开启另外一个在xml配置文件中。
- 先说AOP是什么:面向切面编程,它是OOP面向对象编程的一种扩展。在spring中是基于AspectJ的AOP的开发。
- 有什么好处:之所以称为是OOP的扩展,解决的就是OOP不能解决的问题。AOP能做的事包括权限校验,性能监控,事务管理,等..
- AOP场景问题:看下边的例子
1. 我先提出这样的需求,在进行数据库的数据插入之前进行权限校验:
传统的解决方案是:调用自己写的权限校验方法。
2. 现在提出新的需求了:有多处需要进行权限校验了,三处以内都可以每次都写一遍校验方法,根据代码整洁之道里边的说法,事不过三,超过三次就要重构了。怎么做?
方案是:我们可以使用纵向继承的方式,就是大家都去继承父类,这样做是可以解决问题,但是明显就增加了耦合程度,强行给类扯上关系。并且还有一个问题就是java是单继承的。
我还能想到的是写一个工具类:然后每个都能调用,问题能解决,问题还是强行耦合,并且这需要的肯定不止一个工具类,如果每件事都写一个工具类,这得写多少啊,无形中增加了代码的维护难度。显然这并不是整洁的代码。
3.spring给我们的解决方案是横向抽取。使用的是代理机制 。
spring给我们创建一个代理。并且操作起来很方便,我们只需要进行配置,spring就会替我们产生代理对象,之前的那些操作,都可以使用配置来增强原来的方法,而不是频繁的改代码。
- OK上边已经顺利引出了AOP,也提到了它的底层原理是动态代理,下边就仔细说一下:
动态代理分为:
JDK动态代理:只能对实现接口的类产生代理。
Cglib动态代理:对没有实现接口的类产生代理,注意类不要用final修饰。
AOP的底层是自己识别的。
9.AOP相关术语与应用术语只需要一张图,就可以说明白里边的相关术语:
使用XML的方式使用AOP的步骤:
- 引入约束,高版本的工具并不需要。
- 编写切面类
- 将我们的目标类和切面类都交给spring容器来管理
- spring的AOP仿佛就是一个牵线搭桥的人,将目标类和增强类拉在了一起
来解释一下上边的框里边的内容都是什么:
第一个框看起来很复杂,它叫做spring切入点表达式:*代表任意
10. spring中的通知类型
- 前置通知:在目标方法执行前执行
可以获得切入点的信息。
- 后置通知:在目标方法执行后执行
可以获得方法的返回值
在切面类中加上参数,类型必须是Object 参,参数名必须是result
- 环绕通知: 在目标方法执行前后都执行
可以阻止方法执行
切面类环绕方法
配置
- 异常通知:程序异常的时候执行。
也可以获得异常信息
切面类
配置:
- 最终通知:无论如何,都要执行的。
配置
- 引介通知 (不会用)
未完待续····