• Spring注解开发之@Bean和@ComponentScan


    组件注册

    用@Bean来注册

    1. 搭建好maven web工程

    2. pom加入spring-context,spring-core等核心依赖

    3. 创建实例类com.hjj.bean.Person, 生成getter,setter方法

      public class Person {
          private String name;
          private int age;
      }
      
    4. 创建com.hjj.config.MainConfig

      @Configuration   //告诉spring是一个配置类
      public class MainConfig {
      
          // 给容器中注册一个Bean,类行为返回值的类型,id默认是用方法名作为id
          @Bean("mikePerson")
          public Person person(){
              return new Person("mike",20);
          }
      }
      
    5. 主测试类

      public class MainTest {
          public static void main(String[] args) {
              AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
              Person bean = applicationContext.getBean(Person.class);
              System.out.println(bean);
      
              String[] beanNamesForType = applicationContext.getBeanNamesForType(Person.class);
              for (String type : beanNamesForType) {
                  System.out.println(type);  //配置类中的方法名,注意:通过修改配置类的@bean value也可以修改
              }
          }
      }
      

    @ComponentScan包扫描

    1. 配置类中MainConfig.java

      @Configuration   //告诉spring是一个配置类
      @ComponentScan("com.hjj") // 扫描包的路径
      public class MainConfig {
      
          // 给容器中注册一个Bean,类行为返回值的类型,id默认是用方法名作为id
          @Bean("mikePerson")
          public Person person(){
              return new Person("mike",20);
          }
      }
      
      
    2. 新建测试的com.hjj.controller,service,dao

      @Controller
      public class BookController {
      }
      
      @Repository
      public class BookDao {
      }
      
      @Service
      public class BookService {
      }
      
    3. 单元测试

          @Test
          public void test01(){
              AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
              String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames(); //获取所有组件
              for (String beanDefinitionName : beanDefinitionNames) {
                  System.out.println(beanDefinitionName);  
              }
          }
      
      
    • ComponentScan字段,有includeFilter(),和excludeFilter() 只包含或排除某些组件

      @ComponentScan(value = "com.hjj",excludeFilters={@Filter(type=FilterType.ANNOTATION,classes={Controller.class,Service.class})})
      @ComponentScan(value = "com.hjj",includeFilters={@Filter(type=FilterType.ANNOTATION,classes={Controller.class,Service.class})},userDefaultFilters=false)
      
      // excludeFilter源码
      ComponentScan.Filter[] excludeFilters() default {}; 
      
      // ComponentScan.Filter源码
      @Retention(RetentionPolicy.RUNTIME)
      @Target({})
      public @interface Filter {
        FilterType type() default FilterType.ANNOTATION;
      
        @AliasFor("classes")
        Class<?>[] value() default {};
      
        @AliasFor("value")
        Class<?>[] classes() default {};
      
        String[] pattern() default {};
      }
      
    • @ComponentScan被@Repeatable(ComponentScans.class),可以重复写,用来写不同的执行策略。

    • @ComponentScans 里面可以放ComponentScan类型的值

      @Retention(RetentionPolicy.RUNTIME)
      @Target({ElementType.TYPE})
      @Documented
      public @interface ComponentScans {
          ComponentScan[] value();
      }
      
    • FilterType

      public enum FilterType {
          ANNOTATION,   // 按注解扫描
          ASSIGNABLE_TYPE, // 按给定的类型
          ASPECTJ,  // 可以用aspectJ表达式
          REGEX,  // 正则表达式
          CUSTOM; // 自定义规则
      
          private FilterType() {
          }
      }
      
      • ASSIGNABLE_TYPE

        @ComponentScan(value = "com.hjj",
        includeFilters ={@ComponentScan.Filter(type=FilterType.ASSIGNABLE_TYPE,classes = {BookService.class})})
        
        // config配置如上注解后 bookservice,可以被发现
            @Test
            public void demoTest1(){
                AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
                String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
                for (String beanDefinitionName : beanDefinitionNames) {
                    System.out.println(beanDefinitionName);
                }
            }
        
        
        
      • Custom 可以自定义配置或写业务扫描类的信息,match返回true则是加到组件

        1.复写TypeFilter的match方法
        public class MyTypeFilter implements TypeFilter {
        
            /**
             *
             * @param metadataReader 读取到的当前正在扫描的类的信息
             * @param metadataReaderFactory 可以获取到其他任何类信息
             * @return
             * @throws IOException
             */
            @Override
            public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException {
                // 获取当前类注解的信息
                AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
        
                // 获取当前正在扫描类的信息
                ClassMetadata classMetadata = metadataReader.getClassMetadata();
        
                // 获取当前类资源(类的路径等)
                Resource resource = metadataReader.getResource();
        
                String className = classMetadata.getClassName();
                System.out.println("className:" + className);
                return false;
            }
        }
        
        2. 加上注解
        @Configuration   //告诉spring是一个配置类
        @ComponentScan(value = "com.hjj",
        includeFilters ={
                @ComponentScan.Filter(type=FilterType.CUSTOM,classes = {MyTypeFilter.class})},
                useDefaultFilter=false)
        public class MainConfig {
        
        }
        
        @Test
        public void test01(){
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
        String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
        for (String beanDefinitionName : beanDefinitionNames) {
        System.out.println(beanDefinitionName);
        }
        }
        
        结果
        className:com.hjj.test.IOCTest
        className:com.hjj.MainTest
        className:com.hjj.bean.Person
        className:com.hjj.config.MyTypeFilter
        className:com.hjj.demo.DemoTest
        className:com.hjj.demo.Employee
        className:com.hjj.demo.Manager
        org.springframework.context.annotation.internalConfigurationAnnotationProcessor
        org.springframework.context.annotation.internalAutowiredAnnotationProcessor
        org.springframework.context.annotation.internalCommonAnnotationProcessor
        org.springframework.context.event.internalEventListenerProcessor
        org.springframework.context.event.internalEventListenerFactory
        mainConfig
        
  • 相关阅读:
    集群间如何实现session共享
    详解PHP如何实现单点登录
    jsonp原理详解
    跨站请求CSRF攻击
    防止SQL注入
    在springboot中使用h2数据库
    Datalab实验
    飞步无人驾驶2018届校园招聘在线笔试A轮
    HDU6030 Happy Necklace
    HDU5950 Recursive sequence
  • 原文地址:https://www.cnblogs.com/jimmyhe/p/13549493.html
Copyright © 2020-2023  润新知