大纲
spring注解
- @Configuration: 配置类,就相当于配置文件,告诉Spring这个一个配置类
- @Bean:给容器中注册一个bean,类型就是返回值的类型, 结合@Configuration(full mode)使用或结合@Component(light mode)使用。可以指定initMethod和destroyMethod 指定初始化和销毁方法,多实例对象不会调用销毁方法.(@Bean(initMethod = "init",destroyMethod = "destroy"))
- @ComponentScan:包扫描, (@ComponentScans可以配置多个扫描,@TypeFilter:指定过滤规则,自己实现TypeFilter类)
组件(@Service、@Controller、@Repository):包扫描+组件注解导入注解。 - @Scope:设置组件作用域 1.prototype:多例的2.singleton:单例的(默认值)
- @Lazy: 懒加载,单实例bean默认在容器启动的时候创建对象,懒加载是在容器启动的时候不创建对象,第一次使用(获取)bean时创建对象,并初始化。
- @Conditional({Condition}):按照一定的条件进行判断,满足条件给容器中注册Bean,传入Condition数组,,使用时需自己创建类继承Condition然后重写match方法。
-
@Import [快速给容器中导入一个组件]
- Import(类名),容器中就会自动注册这个组件,id默认是组件的全名
- ImportSelector:返回需要导入的组件的全类名的数组
- ImportBeanDefinitionRegistrar:手动注册bean
- FactoryBean:工厂Bean,交给spring用来生产Bean到spring容器中。创建一个类去实现FactoryBean<T>,其中实现的方法getObject()返回的类型就是一个bean对象,这个对象会添加到容器中,isSingletion()这个方法返回创建的对象是否是单实例bean,返回true代表是单实例bean,返回false代表是多实例bean。可以通过前缀&来获取工厂Bean本身("&类名")。
- @Value:给属性赋值,也可以使用SpEL和外部文件的值
- @PropertySource:读取外部配置文件中的k/v保存到运行环境中,结合@value使用,或使用ConfigurableEnvironment获取。当出现中文乱码的时候需要加encoding="UTF-8"属性。
- @Profile:结合@Bean使用,默认为default环境,可以通过命令行参数来切换环境
- 自定义组件使用Spring容器底层的组件:需要让自定义组件实现xxxAware,(例如:ApplicationContextAware),spring在创建对象的时候,会帮我们自动注入。spring通过BeanPostProcessor机制来实现XXXXAware的自动注入。
-
@Autowried 装配优先级如下:
- 使用按照类型去容器中找对应的组件
- 按照属性名称去作为组件id去找对应的组件
- @Qualifier("beanID"):使用@Qualifier指定需要装配的组件ID,而不使用属性名
- 自动装配默认一定要将属性赋值好,没有就会报错,可以使用@Autowried(required=false)
- @Primary:让Spring进行自动装配的时候,默认首选bean,也可以继续使用@Qualifier指定需要装配的bean名字
- @Qualifier:指定默认的组件,结合@Autowried使用
--标注在构造器:spring创建对象调用构造器创建对象
--标注在方法上: - @Primary:spring自动装配的时候,默认首先bean,配合@Bean使用
- @Resource(JSR250):jsr规范:按照组件名称进行装配
- @Inject(JSR330):jsr规范和@Autowired功能一致,不支持require=false;
Bean生命周期:
- bean的生命周期:bean创建--初始化--销毁的过程
- 容器管理bean的生命周期:我们可以自定义初始化和销毁的方法,容器在bean进行到当前生命周期的时候调用我们自定义的初始化和销毁方法
- 构造(创建对象):
- 单实例:在容器启动的时候创建对象
- 多实例:在每次获取对象的时候创建对象
- 初始化:对象创建完成,并赋值好,调用初始化方法
- 销毁:
- 单实例:容器关闭的时候
- 多实例:容器不会管理这个bean,容器不会调用销毁方法
- 指定初始化和销毁的方式:
- 通过指定init-method和destroy-method:通过@Bean(initMethod = "init",destroyMethod = "destroy")指定初始化和销毁方法
- BeanPostProcessor [interface] :bean的后置处理器
- 在bean初始化前后进行一些处理工作
- postProcessBeforeInitialization:在初始化之前工作
- postProcessAfterInitialization:在初始化之后工作
/**
* 后置处理器:初始化前后进行工作
*/
//将后置处理器加入到容器中
@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessBeforeInitialization----"+"beanName="+beanName+",bean="+bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("postProcessAfterInitialization----"+"beanName="+beanName+",bean="+bean);
return bean;
}
}
spring底层常用的BeanPostProcessor:
* BeanValidationPostProcessor用来实现数据校验 * AutowireAnnotationBeanPostProcessor,@Autowire实现 * ApplicationContextProcessor实现XXXAware的自动注入。
执行时机
doCreateBean -populateBean():给bean的各种属性赋值 -initializeBean():初始化bean -处理Aware方法 -applyBeanPostProcessorsBeforeInitialization:后置处理器的实例化前拦截 -invokeInitMethods:执行@Bean指定的initMethod -applyBeanPostProcessorsAfterInitialization:后置处理器的实例化后拦截
SpringAOP实现原理
使用步骤
- @EnableAspectJAutoProxy 开启基于注解的aop模式
- @Aspect:定义切面类,切面类里定义通知
- @PointCut 切入点,可以写切入点表达式,指定在哪个方法切入
-
通知方法
- @Before(前置通知)
- @After(后置通知)
- @AfterReturning(返回通知)
- @AfterTrowing(异常通知)@Around(环绕通知)
- JoinPoint:连接点,是一个类,配合通知使用,用于获取切入的点的信息
SpringAop原理
-
@EnableAspectJAutoProxy
- @EnableAspectJAutoProxy 通过@Import(AspectJAutoProxyRegistrar.class)给spring容器中导入了一个AnnotationAwareAspectJAutoProxyCreator。
- AnnotationAwareAspectJAutoProxyCreator实现了InstantiationAwareBeanPostProcessor,InstantiationAwareBeanPostProcessor是一个BeanPostProcessor。它可以拦截spring的Bean初始化(Initialization)前后和实例化(Initialization)前后。
- AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation(bean实例化前):会通过调用isInfrastructureClass(beanClass)来判断 被拦截的类是否是基础类型的Advice、PointCut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect),若是则放入adviseBean集合。这里主要是用来处理我们的切面类。
-
AnnotationAwareAspectJAutoProxyCreator的BeanPostProcessorsAfterInitialization(bean初始化后):
- 首先找到被拦截的Bean的匹配的增强器(通知方法),这里有切入点表达式匹配的逻辑
- 将增强器保存到proxyFactory中,
- 根据被拦截的Bean是否实现了接口,spring自动决定使用JdkDynamicAopProxy还是ObjenesisCglibAopProxy
- 最后返回被拦截的Bean的代理对象,注册到spring容器中
-
代理Bean的目标方法执行过程:CglibAopProxy.intercept();
- 保存所有的增强器,并处理转换为一个拦截器链
- 如果没有拦截器链,就直接执行目标方法
- 如果有拦截器链,就将目标方法,拦截器链等信息传入并创建CglibMethodInvocation对象,并调用proceed()方法获取返回值。proceed方法内部会依次执行拦截器链。