Spring注解驱动开发图谱
对于一些复杂、重要、难懂的注解进行详细说明:
package com.anotation.bean;
public class Person {
private String name;
private Integer age;
private String nickName;
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Person(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", nickName=" + nickName + "]";
}
}
package com.anotation.condition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
ClassLoader classLoader = context.getClassLoader();
Environment environment = context.getEnvironment();
BeanDefinitionRegistry registry = context.getRegistry();
String property = environment.getProperty("os.name");
boolean definition = registry.containsBeanDefinition("person");
if(property.contains("Mac OS X")){
return true;
}
return false;
}
}
package com.anotation.condition;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.env.Environment;
import org.springframework.core.type.AnnotatedTypeMetadata;
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
Environment environment = context.getEnvironment();
String property = environment.getProperty("os.name");
if(property.contains("Windows")){
return true;
}
return false;
}
}
package com.anotation.config;
import com.anotation.bean.Person;
import com.anotation.condition.LinuxCondition;
import com.anotation.condition.WindowsCondition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MainConfig2 {
/**
* 比尔盖茨搞windows系统
* @return
*/
@Bean("bill")
@Conditional({WindowsCondition.class})
public Person person01(){
return new Person("Bill Gates",62);
}
/**
* mac搞mac系统
* @return
*/
@Conditional(LinuxCondition.class)
@Bean("mac")
public Person person02(){
return new Person("mac", 48);
}
}
package com.atguigu.test;
import com.anotation.bean.Blue;
import com.anotation.bean.Person;
import com.anotation.config.MainConfig;
import com.anotation.config.MainConfig2;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.core.env.ConfigurableEnvironment;
import java.util.Map;
public class IOCTest {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig2.class);
@Test
public void test03(){
ConfigurableEnvironment environment = applicationContext.getEnvironment();
String property = environment.getProperty("os.name");
System.out.println(property);
Person person = applicationContext.getBean(Person.class);
System.out.println(person);
}
}
运行结果:
Mac OS X
Person [name=mac, age=48, nickName=null]
package org.springframework.context.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
--> Spring IOC容器实例化Bean
--> 调用BeanPostProcessor的postProcessBeforeInitialization方法
--> 调用bean实例的初始化方法
--> 调用BeanPostProcessor的postProcessAfterInitialization方法
Spring容器通过BeanPostProcessor给了我们一个机会对Spring管理的bean进行再加工。比如:我们可以修改bean的属性,可以给bean生成一个动态代理实例等等。一些Spring AOP的底层处理也是通过实现BeanPostProcessor来执行代理包装逻辑的。
package com.anotation.bean;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;
/**
* 后置处理器:初始化前后进行处理工作
* 将后置处理器加入到容器中
* @author zhengchao
*/
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);
return bean;
}
}
package com.anotation.config;
import com.anotation.aop.LogAspects;
import com.anotation.aop.MathCalculator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
/**
* 说明:
* 1、环绕通知,动态代理,手动推进目标方法的运行(joinPoint.procced())
* 2、@EnableAspectJAutoProxy,开启基于注解的aop模式
*
*
* AOP原理:看给容器中注册了什么组件,这个组件什么时候工作,这个组件的功能
* @EnableAspectJAutoProxy注解:
* 1、@EnableAspectJAutoProxy
* @Import(AspectJAutoProxyRegistrar.class):给容器中导入AspectJAutoProxyRegistrar:
* AspectJAutoProxyRegistrar他给容器注册一个AnnotationAwareAspectJAutoProxyCreator
*
* AnnotationAwareAspectJAutoProxyCreator
* AnnotationAwareAspectJAutoProxyCreator
* ->AspectJAwareAdvisorAutoProxyCreator
* ->AbstractAdvisorAutoProxyCreator
* ->AbstractAutoProxyCreator
* implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
* 关注后置处理器(在bean初始化完成前后做的事情)、自动装配BeanFactoryAware
*
*
* AbstractAutoProxyCreator.setBeanFactory()
*
* AbstractAutoProxyCreator.有后置处理器的逻辑
*
* AbstractAdvisorAutoProxyCreator.setBeanFactory()->initBeanFactory()
*
* AnnotationAwareAspectJAutoProxyCreator.initBeanFactory()
*
* 流程
* 1、传入配置类,创建ioc容器
* 2、注册配置类,调用refresh()方法,刷新容器
* 3、registerBeanPostProcessors(beanFactory);注册bean的后置处理器来方便拦截bean的创建
* 1) 先获取ioc容器已经定义了的需要创建对象的所有BeanPostProcessor
* 2) 给容器中加别的BeanPostProcessor
* 3)优先注册实现了PriorityOrdered接口的BeanPostProcessor
* 4)再给容器中注册实现了Ordered接口的BeanPostProcessor
* 5)没有实现优先级接口的BeanPostProcessor
* 6) 注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中
* 创建internalAutoProxyCreator的BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)
* 1、创建Bean的实例
* 2、populateBean:给bean的各种属性赋值
* 3、initializeBean:初始化bean
* 1、invokeAwareMethods() :
* 2、applyBeanPostProcessorsBeforeInitialization() 执行后置处理器postProcessBeforeInitialization
* 3、invokeInitMethods():执行自定义的初始化方法
* 4、applyBeanPostProcessorsAfterInitialization() 执行后置处理器postProcessAfterInitialization
* 4、BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功
* 7) 把BeanPostProcessor注册到BeanFactory中:
* beanFactory.addBeanPostProcessor(beanPostProcessor)
* ========以上是创建和注册AnnotationAwareAspectJAutoProxyCreator的过程 ========
*
* 4、完成BeanFactory剩余的初始化工作:创建剩下的单实例bean
* 1) 遍历获取容器所有的bean,依次创建对象
* 2)、创建bean
*
* AnnotationAwareAspectJAutoProxyCreator【InstantiationAwareBeanPostProcessor】的作用
* 1、每一个bean创建之前,调用postProcessBeforeInstantiation();
* 关心MathCalculator和LogAspect的创建
* 1) 判断当前bean是否在advisedBean中(保存了所有需要增强的bean)
* 2) 判断当前bean是否是基础类型的Advice、Pointcut、Aspect。。。
*
* 2、创建对象 调用postProcessAfterInitialization:
* 1)、获取bean的所有增强器
* 1)获取候选当所有增强器(找到哪些通知方法是需要切入当前bean方法的)
* 2)获取到能在bean使用的增强器
* 3)给增强器排序
* 2)、保存当前bean在advisedBeans中
* 3)、创建bean的代理对象,创建当前bean的代理对象
* 1)获取所有增强器(通知方法)
* 2)保存到proxyFactory中
* 3)创建代理对象
* JdkDynamicAopProxy(config);jdk动态代理
* ObjenesisCglibAopProxy(config);cglib动态代理
* 4)、给容器返回当前组件使用cglib增强了的代理对象
* 5)、以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法
* 3、目标方法执行
* 容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息
* 1)CglibAopProxy.intercept()拦截目标方法的执行
* 2)根据ProxyFactory对象获取将要执行的目标方法的拦截器链
* 3)没有拦截器链,直接执行目标方法
* 拦截器链(每一个通知方法又被包装为方法拦截器,利用MethodInterceptor机制)
* 4)如果有拦截器链,把需要执行的目标对象,目标方法,拦截器链等信息传入创建一个CglibMethodInvocation对象
* 并调用Object retval = mi.proceed()
* 5)拦截器链的触发过程
* 1)如果没有拦截器执行目标方法,或者拦截器的索引和拦截器数组-1大小一样,执行目标方法
* 2)链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行
* 拦截器链的机制,保证通知方法与目标方法的执行顺序
*
* 总结:
* 1)@EnableAspectJAutoProxy注解开启AOP功能
* 2)@EnableAspectJAutoProxy会给容器注册一个组件AnnotationAwareAspectJAutoProxyCreator
* 3)AnnotationAwareAspectJAutoProxyCreator是一个后置处理器
* 4)容器的创建流程:
* 1)registerBeanPostProcessors()注册后置处理器:创建AnnotationAwareAspectJAutoProxyCreator
* 2)finishBeanFactoryInitialization()初始化剩下的单实例bean
* 1)创建业务逻辑组件和切面组件
* 2)AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程
* 3)组件创建完成之后,判断组件是否需要增强
* 是:切面的通知方法包装成增强器(Advisor);给业务逻辑组件创建一个代理对象
* 5)执行目标方便
* 1)代理对象执行目标方法
* 2)CglibAopProxy.intercept()拦截目标方法的执行
* 1)得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)
* 2) 利用拦截器的链式机制,依次进入每一个拦截器进行执行
* 3)效果:
* 正常执行:前置通知-->目标方法-->后置通知-->返回通知
* 异常执行:前置通知-->目标方法-->后置通知-->异常通知
*
*
*/
@EnableAspectJAutoProxy
@Configuration
@ComponentScan(value = "com.anotation.aop")
public class MainConfigOfAOP {
//加这个@ComponentScan(value = "com.anotation.aop"),就不用写下面的@Bean了,
// @Bean
// public MathCalculator calculator(){
// return new MathCalculator();
// }
// @Bean
// public LogAspects logAspects(){
// return new LogAspects();
// }
}
图示拦截目标方法的执行:
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(ExtConfig.class);
Spring容器的refresh()【创建刷新】;
1、prepareRefresh()刷新前的预处理;
1)、initPropertySources()初始化一些属性设置;子类自定义个性化的属性设置方法;
2)、getEnvironment().validateRequiredProperties();检验属性的合法等
3)、earlyApplicationEvents= new LinkedHashSet();保存容器中的一些早期的事件;
2、obtainFreshBeanFactory();获取BeanFactory;
1)、refreshBeanFactory();刷新【创建】BeanFactory;
创建了一个this.beanFactory = new DefaultListableBeanFactory();
设置id;
2)、getBeanFactory();返回刚才GenericApplicationContext创建的BeanFactory对象;
3)、将创建的BeanFactory【DefaultListableBeanFactory】返回;
3、prepareBeanFactory(beanFactory);BeanFactory的预准备工作(BeanFactory进行一些设置);
1)、设置BeanFactory的类加载器、支持表达式解析器...
2)、添加部分BeanPostProcessor【ApplicationContextAwareProcessor】
3)、设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware、xxx;
4)、注册可以解析的自动装配;我们能直接在任何组件中自动注入:
BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
5)、添加BeanPostProcessor【ApplicationListenerDetector】
6)、添加编译时的AspectJ;
7)、给BeanFactory中注册一些能用的组件;
environment【ConfigurableEnvironment】、
systemProperties【Map】、
systemEnvironment【Map】
4、postProcessBeanFactory(beanFactory);BeanFactory准备工作完成后进行的后置处理工作;
1)、子类通过重写这个方法来在BeanFactory创建并预准备完成以后做进一步的设置
======================以上是BeanFactory的创建及预准备工作==================================
5、invokeBeanFactoryPostProcessors(beanFactory);执行BeanFactoryPostProcessor的方法;
BeanFactoryPostProcessor:BeanFactory的后置处理器。在BeanFactory标准初始化之后执行的;
两个接口:BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor
1)、执行BeanFactoryPostProcessor的方法;
先执行BeanDefinitionRegistryPostProcessor
1)、获取所有的BeanDefinitionRegistryPostProcessor;
2)、看先执行实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor、
postProcessor.postProcessBeanDefinitionRegistry(registry)
3)、在执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor;
postProcessor.postProcessBeanDefinitionRegistry(registry)
4)、最后执行没有实现任何优先级或者是顺序接口的BeanDefinitionRegistryPostProcessors;
postProcessor.postProcessBeanDefinitionRegistry(registry)
再执行BeanFactoryPostProcessor的方法
1)、获取所有的BeanFactoryPostProcessor
2)、看先执行实现了PriorityOrdered优先级接口的BeanFactoryPostProcessor、
postProcessor.postProcessBeanFactory()
3)、在执行实现了Ordered顺序接口的BeanFactoryPostProcessor;
postProcessor.postProcessBeanFactory()
4)、最后执行没有实现任何优先级或者是顺序接口的BeanFactoryPostProcessor;
postProcessor.postProcessBeanFactory()
6、registerBeanPostProcessors(beanFactory);注册BeanPostProcessor(Bean的后置处理器)【 intercept bean creation】
不同接口类型的BeanPostProcessor;在Bean创建前后的执行时机是不一样的
BeanPostProcessor、
DestructionAwareBeanPostProcessor、
InstantiationAwareBeanPostProcessor、
SmartInstantiationAwareBeanPostProcessor、
MergedBeanDefinitionPostProcessor【internalPostProcessors】、
1)、获取所有的 BeanPostProcessor;后置处理器都默认可以通过PriorityOrdered、Ordered接口来执行优先级
2)、先注册PriorityOrdered优先级接口的BeanPostProcessor;
把每一个BeanPostProcessor;添加到BeanFactory中
beanFactory.addBeanPostProcessor(postProcessor);
3)、再注册Ordered接口的
4)、最后注册没有实现任何优先级接口的
5)、最终注册MergedBeanDefinitionPostProcessor;
6)、注册一个ApplicationListenerDetector;来在Bean创建完成后检查是否是ApplicationListener,如果是
applicationContext.addApplicationListener((ApplicationListener>) bean);
7、initMessageSource();初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
1)、获取BeanFactory
2)、看容器中是否有id为messageSource的,类型是MessageSource的组件
如果有赋值给messageSource,如果没有自己创建一个DelegatingMessageSource;
MessageSource:取出国际化配置文件中的某个key的值;能按照区域信息获取;
3)、把创建好的MessageSource注册在容器中,以后获取国际化配置文件的值的时候,可以自动注入MessageSource;
beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource);
MessageSource.getMessage(String code, Object[] args, String defaultMessage, Locale locale);
8、initApplicationEventMulticaster();初始化事件派发器;
1)、获取BeanFactory
2)、从BeanFactory中获取applicationEventMulticaster的ApplicationEventMulticaster;
3)、如果上一步没有配置;创建一个SimpleApplicationEventMulticaster
4)、将创建的ApplicationEventMulticaster添加到BeanFactory中,以后其他组件直接自动注入
9、onRefresh();留给子容器(子类)
1、子类重写这个方法,在容器刷新的时候可以自定义逻辑;
10、registerListeners();给容器中将所有项目里面的ApplicationListener注册进来;
1、从容器中拿到所有的ApplicationListener
2、将每个监听器添加到事件派发器中;
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
3、派发之前步骤产生的事件;
11、finishBeanFactoryInitialization(beanFactory);初始化所有剩下的单实例bean;
1、beanFactory.preInstantiateSingletons();初始化后剩下的单实例bean
1)、获取容器中的所有Bean,依次进行初始化和创建对象
2)、获取Bean的定义信息;RootBeanDefinition
3)、Bean不是抽象的,是单实例的,是懒加载;
1)、判断是否是FactoryBean;是否是实现FactoryBean接口的Bean;
2)、不是工厂Bean。利用getBean(beanName);创建对象
0、getBean(beanName); ioc.getBean();
1、doGetBean(name, null, null, false);
2、先获取缓存中保存的单实例Bean。如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来)
从private final Map singletonObjects = new ConcurrentHashMap(256);获取的
3、缓存中获取不到,开始Bean的创建对象流程;
4、标记当前bean已经被创建
5、获取Bean的定义信息;
6、【获取当前Bean依赖的其他Bean;如果有按照getBean()把依赖的Bean先创建出来;】
7、启动单实例Bean的创建流程;
1)、createBean(beanName, mbd, args);
2)、Object bean = resolveBeforeInstantiation(beanName, mbdToUse);让BeanPostProcessor先拦截返回代理对象;
【InstantiationAwareBeanPostProcessor】:提前执行;
先触发:postProcessBeforeInstantiation();
如果有返回值:触发postProcessAfterInitialization();
3)、如果前面的InstantiationAwareBeanPostProcessor没有返回代理对象;调用4)
4)、Object beanInstance = doCreateBean(beanName, mbdToUse, args);创建Bean
1)、【创建Bean实例】;createBeanInstance(beanName, mbd, args);
利用工厂方法或者对象的构造器创建出Bean实例;
2)、applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition(mbd, beanType, beanName);
3)、【Bean属性赋值】populateBean(beanName, mbd, instanceWrapper);
赋值之前:
1)、拿到InstantiationAwareBeanPostProcessor后置处理器;
postProcessAfterInstantiation();
2)、拿到InstantiationAwareBeanPostProcessor后置处理器;
postProcessPropertyValues();
=====赋值之前:===
3)、应用Bean属性的值;为属性利用setter方法等进行赋值;
applyPropertyValues(beanName, mbd, bw, pvs);
4)、【Bean初始化】initializeBean(beanName, exposedObject, mbd);
1)、【执行Aware接口方法】invokeAwareMethods(beanName, bean);执行xxxAware接口的方法
BeanNameAware\BeanClassLoaderAware\BeanFactoryAware
2)、【执行后置处理器初始化之前】applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
BeanPostProcessor.postProcessBeforeInitialization();
3)、【执行初始化方法】invokeInitMethods(beanName, wrappedBean, mbd);
1)、是否是InitializingBean接口的实现;执行接口规定的初始化;
2)、是否自定义初始化方法;
4)、【执行后置处理器初始化之后】applyBeanPostProcessorsAfterInitialization
BeanPostProcessor.postProcessAfterInitialization();
5)、注册Bean的销毁方法;
5)、将创建的Bean添加到缓存中singletonObjects;
ioc容器就是这些Map;很多的Map里面保存了单实例Bean,环境信息。。。。;
所有Bean都利用getBean创建完成以后;
检查所有的Bean是否是SmartInitializingSingleton接口的;如果是;就执行afterSingletonsInstantiated();
12、finishRefresh();完成BeanFactory的初始化创建工作;IOC容器就创建完成;
1)、initLifecycleProcessor();初始化和生命周期有关的后置处理器;LifecycleProcessor
默认从容器中找是否有lifecycleProcessor的组件【LifecycleProcessor】;如果没有new DefaultLifecycleProcessor();
加入到容器;
写一个LifecycleProcessor的实现类,可以在BeanFactory
void onRefresh();
void onClose();
2)、 getLifecycleProcessor().onRefresh();
拿到前面定义的生命周期处理器(BeanFactory);回调onRefresh();
3)、publishEvent(new ContextRefreshedEvent(this));发布容器刷新完成事件;
4)、liveBeansView.registerApplicationContext(this);
======总结===========
1)、Spring容器在启动的时候,先会保存所有注册进来的Bean的定义信息;
1)、xml注册bean;
2)、注解注册Bean;@Service、@Component、@Bean、xxx
2)、Spring容器会合适的时机创建这些Bean
1)、用到这个bean的时候;利用getBean创建bean;创建好以后保存在容器中;
2)、统一创建剩下所有的bean的时候;finishBeanFactoryInitialization();
3)、后置处理器;BeanPostProcessor
1)、每一个bean创建完成,都会使用各种后置处理器进行处理;来增强bean的功能;
AutowiredAnnotationBeanPostProcessor:处理自动注入
AnnotationAwareAspectJAutoProxyCreator:来做AOP功能;
xxx....
增强的功能注解:
AsyncAnnotationBeanPostProcessor
....
4)、事件驱动模型;
ApplicationListener;事件监听;
ApplicationEventMulticaster;事件派发:
to be continue...