本篇部分内容来源于网络,加上个人总结归纳,另外加上一些自己的见解,于是本篇文章诞生。感谢部分内容的提供者。
文章目录
-
- 1、 Spring的 IOC和AOP机制 ?
- 2、 Spring中 `@Autowired` 和 `@Resource` 注解的区别?
- 3、依赖注入的方式有几种,各是什么?
- 4、讲一下什么是 Spring ?
- 5、 Spring的AOP理解:
- 6、Spring的IOC理解
- 7、解释一下 Spring bean的生命周期
- 8、 解释Spring支持的几种bean的作用域
- 9、 Spring基于xml注入bean的几种方式:
- 10、Spring框架中都用到了哪些设计模式?
- 11、聊一聊Spring中@Transactional注解及其失效的六种场景
- 12、Spring AOP(思想)以及AspectJ框架(重点)
1、 Spring的 IOC和AOP机制 ?
(1)我们是在使用 Spring框架的过程中,其实就是为了使用 IOC(控制反转)、依赖注入(DI与IOC一样)和AOP(面向切面编程),这两个也是 Spring 的灵魂。
(2)主要用到的设计模式有工厂模式和代理模式
IOC就是典型的工厂模式,AOP就是典型的代理模式的体现。
代理模式是常用的Java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供特定的服务。
(3)Spring的 IoC容器是 Spring的核心,Spring AOP是 Spring框架的重要组成部分。
IoC:控制反转:
在传统的程序设计中,当调用者需要被调用者的协助时,通常由调用者来创建被调用者的实例。但在 Spring里创建被调用者的工作不再由调用者来完成,因此控制反转(IoC);创建被调用者实例的工作通常由 Spring容器来完成,然后注入调用者,因此也被称为依赖注入(DI),依赖注入和控制反转是同一个概念。
面向切面编程(AOP)是以另一个角度来考虑程序结构,通过分析程序结构的关注点来完善面向对象编程(OOP)。OOP将应用程序分解成各个层次的对象,而AOP将程序分解成多个切面(切面就是要添加的非核心功能)。Spring AOP 只实现了方法级别的连接点,在J2EE应用中,AOP拦截到方法级别的操作就已经足够。在 Spring中,未来使 IoC方便地使用健壮、灵活的企业服务,需要利用 Spring AOP实现为IoC和企业服务之间建立联系。
IOC控制反转也叫依赖注入。利用了工厂模式将对象交给容器管理,你只需要在 Spring 总配置文件中配置相应的bean,以及设置相关的属性,让 Spring容器来生成类的实例对象以及管理对象。在 Spring容器启动的时候,Spring会把你在配置文件中配置的 bean都初始化好(这里就会涉及到复杂的 bean 创建的生命周期),然后在你需要调用的时候,就把它已经初始化好的那些 bean 分配给你需要调用这些 bean的类(假设这个类名是A),分配的方法就是调用 A 的 setter方法来注入,而不需要你在A里面 new 这些 bean了。
问:控制反转和依赖注入式同一个概念吗?
控制反转和依赖注入是对同一件事情的不同描述,从某个方面讲,就是它们描述的角度不同。
依赖注入是从应用程序的角度在描述,可以把依赖注入描述完整点:应用程序依赖容器创建并注入它所需要的外部资源;
而控制反转是从容器的角度在描述,描述完整点:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。
问:bean 和 Java对象的区别:
① bean 是经历过完整的 bean 生命周期生成的放在单例池(singletonObjects)中的对象(大部分bean 是这样的)是有 Spring 容器创建出来的;
② bean 是一个Java对象,而Java对象并不一定是 bean(这一点并没有官方做支撑,个人理解)。
③ bean 创建好之后它的属性就是赋完值的,也就是 bean 是属性不是默认值的一个对象,而 new 出来的对象的属性是默认值。
AOP:面向切面编程(Aspect-Oriented Programming):
AOP可以说是对OOP的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。例如日志功能、事务管理、权限认证、异常处理等等吧。日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。将程序中的交叉业务逻辑(比如安全,日志,事务等),封装成一个切面,然后注入到目标对象(具体业务逻辑)中去。
实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。
简单点解释,比方说你想在你的 service 层所有类中都加上一个打印"你好"的功能,这时就可以用 AOP 思想来做。你先写个类及其方法,方法实现打印"你好",然后将这个类都注入到每一个需要实现打印的类中即可实现。
2、 Spring中 @Autowired
和 @Resource
注解的区别?
@Resource和@Autowired都是做bean的注入时使用,其实@Resource并不是 Spring 的注解,它的包是javax.annotation.Resource,需要导入,但是Spring支持该注解的注入。
(1)共同点
两者都可以写在字段和setter方法上。两者如果都写在字段上,那么就不需要再写setter方法。
(2)不同点
(1)@Autowired
@Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;只按照 byType(类型)注入。
@Autowired注解是按照类型(byType)装配依赖对象,默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的 required
属性为 false。如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。如下:
(2)@Resource
@Resource默认按照 byName
自动注入,由J2EE提供,需要导入包javax.annotation.Resource。
@Resource有两个重要的属性:name
和 type
,而Spring将@Resource注解的name属性解析为bean的名字,而type属性则解析为bean的类型。所以,如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。如果既不制定name也不制定type属性,这时将通过反射机制使用byName自动注入策略。
注:最好是将@Resource放在 setter
方法上,因为这样更符合面向对象的思想,通过set、get去操作属性,而不是直接去操作属性。
@Resource装配顺序:
①如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。
②如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。
③如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。
④如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。
@Resource的作用相当于@Autowired,只不过@Autowired按照byType自动注入。
更加详细的 @Autowired、@Resource 的介绍见,