​Spring:IOC、DI 和 AOP

1.Spring

        Spring 指的是 Spring Framework(Spring 框架),它是一个开源框架,是针对bean的生命周期进行管理的轻量级容器(lightweight container)。

Spring 两大核心内容

Spring IOC(Inversion of Control):控制反转,把创建new 对象过程交给 Spring 进行管理。通过依赖注入(DI),装配对象,配置对象,并且管理这 些对象的整个生命周期

Spring DI(Dependency Injection ):依赖注入,通过配置文件给属性赋值

Spring Aop(Aspect Oriented Programming):面向切面编程,不修改源代码进行功能增强

1.1 Spring Bean的作用域(Scope:指Bean的作用范围,value=singleton/prototype)

Bean 的作用域

1

singleton

(单例模式)

在每个 Spring IOC 容器中只有一个实例。Spring 框架中的单例 bean 是线程不安全的

默认模式,单例的

2

prototype

(原型/多例模式)

每次调用getBean()都会生成一个新的对象,一个Spring IOC 容器里可以有多个实例多例的
3

request

(HTTP请求)

每次 http 请求都会创建一个beanweb项目,Spring 创建一个 Bean 的对象,将对象存入到 request 域中:一次请求期间有效
4

session

(会话)

在一个 HTTP Session 中,一 个 bean 定义对应一个实例(同一个 Session共享一个实例)web项目,Spring 创建一个 Bean 的对象,将对象存入到 session 域中:一次会话期间有效
5

global-session

(全局会话)

在一个全局的 HTTP Session 中,一个 bean 定义对应一个实例WEB 项目中,应用在 Portlet 环境,如果没有 Portlet 环境那么globalSession 相当于 session

1.2 Spring 八大模块 

1Spring JDBCJava 数据库连接
2Spring ORM用于支持 Hibernate、Mybatis 等 ORM 工具
3Spring JMSJava 消息服务
4Spring Web为创建 Web 应用程序提供支持。
5Spring AOP提供面向方面的编程实现。
6Spring Aspects该模块为集成 AspectJ 提供支持。
7Spring Core基础,提供 IOC 和 DI 能力,可以说 Spring 其他所有的功能都依赖于该类库。
8Spring Test提供了对 JUnit 和 TestNG 测试框架的支持

1.3 Spring Bean的生命周期:

1.实例化 Instantiation:实例化一个 Bean 对象

2.属性赋值 Populate:为 Bean 设置相关属性和依赖

3.初始化 Initialization:有 Aware 接口的依赖注入、BeanPostProcessor 在初始化前后的处理以及 InitializingBean 接口 和 init-method 的初始化操作

4.销毁 Destruction:有注册Destruction相关销毁回调接口,(使用中:业务代码功能调用实现),最后通过DisposableBean 接口 和 destory-method 进行销毁

2.Spring IOC(Inversion of Control),控制反转

        Spring IOC(Inversion of Control),控制反转,把对象的创建工作交给 Spring 框架(工厂 Spring),我们不需要自己去new这个对象,只管问工厂 Spring IOC 容器 要(负责对象的实例化、对象的初始化、对象和对象之间的依赖关系配置、对象的销毁、对象提供对象的查找等操作,对象的整个生命周期都是 Spring IOC容器来控制的,使用IOC容器进行管理后,则不需要我们手动通过new的方式去创建对象,由IOC容器帮我们组装好直接用即可)。由Spring IOC容器管理对象的生命周期:底层原理就是Spring Bean的生命周期:

实例化 Instantiation,属性赋值 Populate,初始化 Initialization,销毁 Destruction。

2.1 Spring IOC 声明bean的注解

注解说明
@Component用在类上,相当于bean标签 <bean />
@Controller用在web层类上,配置一个bean(是@Component的衍生注解)
@Service用在service层类上,配置一个bean(是@Component的衍生注解)
@Repository用在dao层类上,配置一个bean(是@Component的衍生注解)

2.2 Spring IOC三种注入方式

(1)XML:Bean实现类来自第三方类库,例如DataSource等。需要命名空间等配置,例如:context,aop,mvc。

(2)注解:在开发的类使用@Controller,@Service等注解

(3)Java配置类:通过代码控制对象创建逻辑的场景。例如:自定义修改依赖类库。

3.Spring AOP(Aspect Oriented Programming),面向切面编程

        Spring AOP 通常用来处理 事务,日志记录,权限校验和管理 和 缓存 等

        Spring中的AOP代理还是离不开Spring的IOC容器,代理的生成,管理及其依赖关系都是由IOC容器负责。

Spring 事务管理
1编程式的事务管理通过TransactionTemplate手动管理事务 在实际应用中很少使用,原因是要修改原来的代码,加入事务管理代码 (侵入性 )
2声明式事务管理(XML配置)Spring的声明式事务是通过AOP实现的(环绕通知) 开发中经常使用(代码侵入性最小)——推荐使用!

3.1 Spring AOP:切面、切入点、连接点、通知

连接点(Joint Point)程序执行过程中明确的点,一般是方法的调用,异常的抛出
切入点(Pointcut)

带有通知的连接点,在程序中主要体现为书写切入点表达式

增强/通知(Advice)

AOP 框架中的增强处理 。有五种类型的通知:@Before,@After,@AfterReturning,@AfterThrowing,@Around

切面(Aspect)

通常是一个类,切面(Aspect)是切入点(Pointcut)和通知(Advice)的结合

目标对象(Target object)目标对象(Target object)是指将要被增强的对象
织入(Weaving)

将增强处理添加到目标对象中,并创建一个被增强的代理对象

引入(Introduction)允许我们向现有的类添加新的方法或者属性

3.2 五种类型 通知(Advice)方法

1@Before在执行目标方法之前运行前置通知
2@After在目标方法运行结束之后,无论方法执行是否成功后置通知
3@AfterReturning仅当方法成功完成后执行的通知返回通知
4@AfterThrowing在方法抛出异常退出时执行的通知异常通知
5@Around在方法执行之前和之后调用的通知(前置通知+执行方法+后置通知)环绕通知

3.3 AOP 代理(Proxy):AOP框架创建的对象,代理就是目标对象的加强

AOP代理(Proxy)
1JDK动态代理基于 接口Spring 默认使用JDK动态代理
2CGLIB动态代理基于 子类在需要代理类而不是代理接口的时候,Spring会自动切换为使用CGLIB代理
@EnableAsync配置类中通过此注解开启对异步任务的支持在类上
@Async在实际执行的bean方法使用该注解来声明其是一个异步任务(方法上或类上所有的方法都将异步,需要@EnableAsync开启异步任务)在方法上
@Aspect表示当前类是切面类
切面类:是用来给业务方法增加功能的类,在这个类中有切面的功能代码
在类上

4.Spring DI(Dependency Injection),依赖注入

        Spring DI(Dependency Injection),依赖注入,托管类里面有什么属性需要完成赋值工作,把这个赋值的工作交给Spring来做。由Spring 把属性需要用到的值赋值(注入)进来就称之为依赖注入(让Spring给托管类的属性,赋值)。在pom.xml有一个依赖项,用来导入外部的资源,而这里的依赖注入,导入的不是外部的资源,而是对象。

DI的实现有两种:
        1.在spring的配置文件中, 使用标签和属性完成,基于XML的实现
        2.使用spring中的注解,完成属性赋值, 基于注解的实现

4.1 Spring DI 依赖注入的注解

注解说明
@Autowired相当于property标签的ref 注入对象 <property name="" ref=""/>
@Qualifer结合@Autowired使用,用于根据名称(标识符)注入依赖(用于给@Autowired指定id值)
@Resource相当于@Autowired+@Qualifer
@Value相当于property标签的value ,注入普通 的属性 <property name="" value=""/>

4.2 Spring DI 依赖注入方式

1Set方法注入注入是最简单、最常用的注入方式,支持注解+xml
2构造器注入是指带有参数的构造函数注入,支持注解+xml
3静态工厂的方法注入通过调用静态工厂的方法来获取自己需要的对象,只支持xml
4实例工厂的方法注入获取对象实例的方法不是静态的,所以你需要首先new工厂类,再调用普通的实例方法,只支持xml

1.set-注解,如@Autowired,@Resource(@Autowired+@Qualifer)

public class UserService {
 
 @Autowired //注解注入
 private UserDao userDao;

 public void login() {
  userDao.login();
 }
}

2.set-xml

<bean name="userService" class="com.service.UserService">
        <!--这里是property-->
        <property name="userDao" ref="userDao"/>
</bean>
<bean name="userDao" class="com.dao.UserDao">
</bean>

3.构造-注解方式

public class UserService {
 private UserDao userDao;

 @Autowired  //注解到构造方法处
 public UserService(UserDao userDao) {
  this.userDao = userDao;
 }
​​​​​​​
 public void login() {
  userDao.login();
 }
}

4.构造-xml 

<bean name="userService" class="com.service.UserService">
        <!--这里是constructor-arg-->
        <constructor-arg index="0" ref="userDao"/>
</bean>
<bean name="userDao" class="com.dao.UserDao">
</bean>

5.静态工厂-xml

<bean name="userService" class="com.service.UserService">
​​​​​​​        <!--property属性-->
        <property name="staticUserDao" ref="staticUserDao"/>

</bean>
        <!--UserDao staticUserDao=Factory.initUserDao() -->
        <bean name="staticUserDao" class="com.Factory" factory-method="initUserDao">
</bean>

6.实例工厂-xml

<bean name="userService" class="com.service.UserService">
        <property name="staticUserDao" ref="staticUserDao" />
</bean>

<!--UserDao staticUserDao=factory.initUserDao() -->
<bean name="staticUserDao" factory-bean="factory" factory-method="initUserDao">
</bean>
 
<!--Factory factory = new Factory() -->
<bean name="factory" class="com.Factory">
</bean>

7.了解@bean的方式

 @Configuration
 public class AppConfig {
     // 使用@Bean 注解表明myBean需要交给Spring进行管理
     // 未指定bean 的名称,默认采用的是 "方法名" + "首字母小写"的配置方式
     @Bean
     public MyBean myBean(){
         return new MyBean();
    }
 }


版权声明:本文为m0_61601521原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。