了解SpringIOC,需要先对Spring有基本的认识,Spring是对bean的生命周期管理的一个轻量级容器。解决了J2EE开发过程常见的问题。Spring框架主要由七部分组成,分别是
Spring Core、 Spring AOP、 Spring ORM、 Spring DAO、Spring Context、 Spring
Web和 Spring Web MVC。
Bean的创建生命周期
被spring管理的对象就叫做Bean.Bean肯定是对象,但是对象不一定就是Bean(比如new 出来的就只是对象,不是Bean)。
Spring在启动的时候就会扫描由@Component(@Controller,@Service,@Repository这三个注解都是@Component的衍生注解)注解的类,实例化这个对象,再利用该对象的(@AutoWired和@Resource)DI的依赖注入(这一步就相当于是spring给这个对象赋值),spring才会把这个对象当作bean来管理起来。某个类---->通过(无参的构造方法)实例化----->得到对象--------->通过依赖注入------->得到bean.
在SpringApplication执行run方法的时候,会执行prepareContext和refreshContext这两步操作,这两操作完成了bean的生命周期的创建。
- 加载bean定义
执行run方法会调用loadBeanDefinitions加载spring容器中的bean,并将这些bean放置在beanDefinitionMap这样的集合中,加载bean定义的过程 run() refreshContext() refresh() obtainFreshBeanFactory() refreshBeanFactory() loadBeanDefinitions();通过loadBeanDefinitions()扫描所有xml配置、注解的bean,并将bean记录在beanDefinitionMap中。- 创建bean对象
通过createBean遍历beanDefinitionMap创建bean,创建bean对象的过程run() refreshContext() refresh() finishBeanFactoryInitialization() preInstantiateSingletons() getBean() doGetBean();
- 构建对象
通过createBeanInstance获取到这个bean的构造方法,如果这个bean只有一个构造方法,就获取这个bean,如果这个bean由多个构造方法,就获取带@Autowire的构造方法的bean。如果多个构造方法都没有@Autowire,就获取带无参构造方法的bean。然后根据类查找和参数名查找,在进行构建对象。- 填充属性
通过populateBean来进行填充对象,通常是解析@Autowire注解的变量。相当于就是给对象赋值- 初始化实例
通过initializeBean来进行初始化对象,初始化完成后,bean就可以应用了。- 注册销毁
为了让bean优雅的销毁,通过注册registerDisposableBean方法,将实现了DisposableBean的bean进行注册,这样在销毁的时候,执行destory方法就行了。- 添加到单例池
通过addSingleton将这些完整的bean对象放到单例池singletonObjects里面就可以被获取和使用了。- 销毁bean对象
当执行close()销毁时,先执行“销毁前处理器”postProcessBeforeDestruction。这里就会执行@PreDestroy注解的方法,然后通过destoryBean一个个销毁Bean对象。销毁时会执行destory()方法,在执行完成该方法后,会通过“客户销毁方法”invokeCustomDestoryMethod()来执行在bean上自定义的destoryMethod()方法。
SpringIOC
- 控制反转?
springIOC容器去控制bean的生命周期,管理对bean对象的创建、实例及销毁。而实现控制反转。控制就是控制bean对象。反转就是将由资源的使用者去创建,现在由springIOC为你创建。控制反转的手段是依赖注入。
- 什么是依赖注入?
依赖注入有三种方式set注入、构造器注入和字段注入。依赖注入的本质就是装配,装配是依赖注入的具体行为,这就是两者的关系。
//构造器注入
EnterpriseService service;
public EnterpriseController(EnterpriseService service) {
this.service = service;
}
//set注入
EnterpriseService service;
public void setService(EnterpriseService service) {
this.service = service;
}
字段注入
@Autowired
EnterpriseService service;
- 装配
创建对象之间的协作关系称之为装配,也就是说当一个对象的属性是另一个对象的时候,实例化时就需要为这个对象进行实例化,这个过程就是装配。
在传统的依赖注入配置中,我们必须要明确要给属性装配哪一个bean的引用,一旦bean很多,就不好维护了。基于这样的场景,spring使用注解来进行自动装配,解决这个问题。
自动装配就是开发人员不必知道具体要装配哪个bean的引用,这个识别的工作会由spring来完成。与自动装配配合的还有“自动检测”,这个动作会自动识别哪些类需要被配置成bean,进而来进行装配。这样我们就明白了,自动装配是为了将依赖注入“自动化”的一个简化配置的操作。
SpringAOP
什么是aop:面向切面编程,利用AOP可以将业务的代码实现进行隔离,从而降低业务上的各部分耦合性,提高代码可重用性,提高代码开发的效率。aop把公共的业务(日志、事物、安全)进行管理,使开发人员只专注于代码实现。其本质还是动态代理。
package com.kuang.config;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
@Aspect
@Component
public class AnnotationPointcut {
@Before("execution(* com.kuang.service.UserServiceImpl.*(..))")
public void before(){
System.out.println("---------方法执行前---------");
}
@After("execution(* com.kuang.service.UserServiceImpl.*(..))")
public void after(){
System.out.println("---------方法执行后---------");
}
@Around("execution(* com.kuang.service.UserServiceImpl.*(..))")
public void around(ProceedingJoinPoint jp) throws Throwable {
System.out.println("环绕前");
System.out.println("签名:"+jp.getSignature());
//执行目标方法proceed
Object proceed = jp.proceed();
System.out.println("环绕后");
System.out.println(proceed);
}
}