Spring注解

  1. @Configuration & @Bean 配置类 & 添加组件

    • @Configuration 定义一个配置类替换xml文件,在配置类中可以通过方法注册组件,方法的返回值是组件的类型,返回值是组件对象,组件名默认为方法名
    • @Bean 标注在配置类的方法上,将方法的返回对象注册到IOC容器中,@Bean内有一个name参数可以是显示指定组件名称

      1. @Configuration
      2. public class MyConfig {
      3. @Bean("print")
      4. public PrintBean printBean(){
      5. return new PrintBean();
      6. }
      7. }
  2. @ComponentScan & TypeFilter 组件扫描

@ComponentScan 注解中可以配置扫描路径(basePackage),扫描的类文件,包含的组件和排除的组件

  1. @ComponentScan(basePackages = {"org.example.controller","org.example.dao"})
  2. @ComponentScan(basePackageClasses = {UserController.class, UserService.class})
  3. @ComponentScan(
  4. basePackages = {"org.example"},
  5. includeFilters = {
  6. @ComponentScan.Filter(type = FilterType.ANNOTATION,classes = {Controller.class}),
  7. @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE,classes = {UserController.class, UserService.class})
  8. },
  9. excludeFilters = {
  10. @ComponentScan.Filter(classes = {Repository.class,Service.class}),
  11. @ComponentScan.Filter(type = FilterType.CUSTOM,classes = {MyTypeFilter.class})
  12. }
  13. )

@ComponentScan.Filter注解中,type属性为FilterType的枚举类型

  1. public enum FilterType {
  2. //按照注解进行过滤
  3. ANNOTATION,
  4. //按照制定类型进行过滤
  5. ASSIGNABLE_TYPE,
  6. //按照ASPECTJ表达式进行过滤
  7. ASPECTJ,
  8. //按照正则表达式进行过滤
  9. REGEX,
  10. //按照自定义规则进行过滤
  11. CUSTOM
  12. }

如果预置的几种方式不能满足需求,需要使用自定义过滤规则可以实现TypeFilter接口,重写match()方法

  1. public class MyTypeFilter implements TypeFilter {
  2. @Override
  3. /**
  4. * @return true 表示符合过滤规则
  5. * false 没有匹配过滤规则
  6. */
  7. public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
  8. //获取当前类的注解信息
  9. AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
  10. //获取当前正在扫描类的信息
  11. ClassMetadata classMetadata = metadataReader.getClassMetadata();
  12. //获取当前资源类(类路径)
  13. Resource resource = metadataReader.getResource();
  14. //返回类的全限定名
  15. String className = classMetadata.getClassName();
  16. if (className.substring(className.lastIndexOf(".")+1).equalsIgnoreCase("userController")){
  17. return true;
  18. }
  19. return false;
  20. }
  21. }
  1. **@Scope**设置组件作用域:

    • singleton 单例(默认)
    • prototype 多例
  2. @Lazy 懒加载

  3. **@Conditional** 按条件注册

可以标在类上或方法上,@Conditional的注解中需要传入一个Condition数组,Condition数组的matches()方法返回true的会进行组件注册。标在类上满足条件这个类的所有对象才会注册到容器中,标在方法上,满足条件,该方法的组件才会注册到容器中。

  1. public class WindowsCondition implements Condition {
  2. @Override
  3. public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
  4. //获取IOC容器的BeanFactory
  5. ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
  6. //获取类加载器
  7. ClassLoader classLoader = context.getClassLoader();
  8. //获取到BeanDefinition的注册类
  9. BeanDefinitionRegistry registry = context.getRegistry();
  10. //获取到当前环境信息
  11. Environment environment = context.getEnvironment();
  12. if (environment.getProperty("os.name").contains("Windows")){
  13. return true;
  14. }
  15. return false;
  16. }
  17. }
  1. @Import 给容器中注册组件

给容器中注册组件方法

  • 包扫描+组件标注注解[@Controller/@Service/@Repository/Component]
  • @Bean[导入第三方包里的组件]
  • @Import[快速给容器导入组件]
    • @Import (要导入的组件):容器中会自动注册这个组件,id为类的全限定名
    • ImportSelector返回需要导入组件的全限定名数组
    • ImportBeanDefinitionRegistrar:手动注册组件
  • FactoryBean 使用Spring提供的FactoryBean

    • 默认获取到的 工厂调用getObject()创建的对象
    • 要获取工厂Bean本身,需要在id前加一个’&

      1. public interface BeanFactory {
      2. String FACTORY_BEAN_PREFIX = "&";
      3. ....
      4. }
  1. Bean的生命周期

Bean的生命周期:
image.png

容器管理Bean的生命周期:
我们可以自定义初始化和销毁方法,容器在bean进行到当前生命周期的时候来调用我们自定义的初始化和销毁方法
构造(对象创建)

  • 单实例Singleton:在容器启动时创建对象
  • 多实例Prototype:在每次获取时创建对象

初始化

  • 对象创建完成,并赋值后,调用初始化方法

销毁

  • 单实例Singleton:容器关闭时调用销毁方法
  • 多实例Prototype:容器并不管理多实例Bean,容器不会调用这个Bean的销毁方法

指定初始化及销毁方法;

  • 通过@Bean指定init-mehoddestroy-method
  • 实现InitializingBeanDisposableBean接口
  • 使用JSR250标准推出的注解**@PostConstruct****@PreDestroy**

BeanPostProcessor后置处理器

  1. public interface BeanPostProcessor {
  2. /**
  3. * 支持BeanPostProcessor在一个bean对象的任何初始化方式之前的回调,
  4. * 并可以返回一个bean的包装对象或不做改变
  5. */
  6. @Nullable
  7. default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  8. return bean;
  9. }
  10. /**
  11. * 支持BeanPostProcessor在一个bean对象的任何初始化方式之后的回调,
  12. * 并可以返回一个bean的包装对象或不做改变
  13. */
  14. @Nullable
  15. default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  16. return bean;
  17. }
  18. }

Bean生命周期顺序
image.png

  1. **@Value** & @**PropertySource**

**@Value** 可以给类的属性赋值,一共有三种方式

  • 基本数值
  • 使用SpEL:#{}
  • 使用${},可以读出配置文件内的值

**@PropertySource** 将配置文件与资源类绑定,这样使用#{}就能读到配置文件中的k/v值,但是注意如果配置文件内有中文字符,还需要设置encode="UTF-8",否则会出现乱码问题

  1. **@Autowired** & **@Qualifier** & **@Primary**

@Autowired 自动注入

  1. 默认按照类型去容器中查找组件进行注入
  2. 如果容器中有多个类型相同的组件,则会按照属性名进行查找
  3. **@Qualifier** 按照指定的id查找组件
  4. 自动装配默认容器中一定要有可以注入的组件,否则会报错可以修改**required = false**
  5. **@Primary**当容器中没有符合条件的组件会自动注入**@Primary**标注的组件
  1. **@Resource** **@Inject** 都可以实现自动注入,但是这两个注解都是Java规范
    • **@Resource** 优先按照名字进行匹配,如果查找不到再按照类型进行匹配,并且不支持**@Qualifier****@Primary**
    • **@Inject**支持**@Qualifier****@Primary**但注解内不含有属性所以不支持**required = false**


  1. AOP

通知方法:
**@Before** 在目标方法运行之前执行
**@After** 在目标方法运行结束后运行
**@AfterReturning** 在目标方法返回之后运行
**@AfterThrowing** 在目标方法抛出异常时执行
应该将切面类和目标类交由IOC容器管理,在切面类上标注**@Aspect**表明这是一个切面,并在配置类上开启自动代理**@EnableAspectJAutoProxy**