Spring基于注解开发

大纲

image.png

 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 [快速给容器中导入一个组件]

    1. Import(类名),容器中就会自动注册这个组件,id默认是组件的全名
    2. ImportSelector:返回需要导入的组件的全类名的数组
    3. 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 装配优先级如下:

    1. 使用按照类型去容器中找对应的组件
    2. 按照属性名称去作为组件id去找对应的组件
    3. @Qualifier("beanID"):使用@Qualifier指定需要装配的组件ID,而不使用属性名
    4. 自动装配默认一定要将属性赋值好,没有就会报错,可以使用@Autowried(required=false)
    5. @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实现原理

使用步骤

  1. @EnableAspectJAutoProxy 开启基于注解的aop模式
  2. @Aspect:定义切面类,切面类里定义通知
  3. @PointCut 切入点,可以写切入点表达式,指定在哪个方法切入
  4. 通知方法

    • @Before(前置通知)
    • @After(后置通知)
    • @AfterReturning(返回通知)
    • @AfterTrowing(异常通知)@Around(环绕通知)
  5. JoinPoint:连接点,是一个类,配合通知使用,用于获取切入的点的信息

SpringAop原理

  1. @EnableAspectJAutoProxy

    • @EnableAspectJAutoProxy 通过@Import(AspectJAutoProxyRegistrar.class)给spring容器中导入了一个AnnotationAwareAspectJAutoProxyCreator。
    • AnnotationAwareAspectJAutoProxyCreator实现了InstantiationAwareBeanPostProcessor,InstantiationAwareBeanPostProcessor是一个BeanPostProcessor。它可以拦截spring的Bean初始化(Initialization)前后和实例化(Initialization)前后。
  2. AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation(bean实例化前):会通过调用isInfrastructureClass(beanClass)来判断 被拦截的类是否是基础类型的Advice、PointCut、Advisor、AopInfrastructureBean,或者是否是切面(@Aspect),若是则放入adviseBean集合。这里主要是用来处理我们的切面类。
  3. AnnotationAwareAspectJAutoProxyCreator的BeanPostProcessorsAfterInitialization(bean初始化后):

    1. 首先找到被拦截的Bean的匹配的增强器(通知方法),这里有切入点表达式匹配的逻辑
    2. 将增强器保存到proxyFactory中,
    3. 根据被拦截的Bean是否实现了接口,spring自动决定使用JdkDynamicAopProxy还是ObjenesisCglibAopProxy
    4. 最后返回被拦截的Bean的代理对象,注册到spring容器中
  4. 代理Bean的目标方法执行过程:CglibAopProxy.intercept();

    1. 保存所有的增强器,并处理转换为一个拦截器链
    2. 如果没有拦截器链,就直接执行目标方法
    3. 如果有拦截器链,就将目标方法,拦截器链等信息传入并创建CglibMethodInvocation对象,并调用proceed()方法获取返回值。proceed方法内部会依次执行拦截器链。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值