@ComponentScan 详解

@ComponentScan

  1 @Retention(RetentionPolicy.RUNTIME)
  2 @Target(ElementType.TYPE)
  3 @Documented
  4 @Repeatable(ComponentScans.class)
  5 public @interface ComponentScan {
  6 
  7    /**
  8     * 扫描路径
  9     * @ComponentScan(value = "spring.annotation.componentscan")
 10     */
 11    @AliasFor("basePackages")
 12    String[] value() default {};
 13 
 14    /**
 15     * 扫描路径
 16     */
 17    @AliasFor("value")
 18    String[] basePackages() default {};
 19 
 20    /**
 21     * 指定扫描类
 22     * @ComponentScan(basePackageClasses = {BookDao.class, BookService.class})
 23     */
 24    Class<?>[] basePackageClasses() default {};
 25 
 26    /**
 27     * 命名注册的Bean,可以自定义实现命名Bean,
 28     * 1、@ComponentScan(value = "spring.annotation.componentscan",nameGenerator = MyBeanNameGenerator.class)
 29     * MyBeanNameGenerator.class 需要实现 BeanNameGenerator 接口,所有实现BeanNameGenerator 接口的实现类都会被调用
 30     * 2、使用 AnnotationConfigApplicationContext 的 setBeanNameGenerator方法注入一个BeanNameGenerator
 31     * BeanNameGenerator beanNameGenerator = (definition,registry)-> String.valueOf(new Random().nextInt(1000));
 32     * AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
 33     * annotationConfigApplicationContext.setBeanNameGenerator(beanNameGenerator);
 34     * annotationConfigApplicationContext.register(MainConfig2.class);
 35     * annotationConfigApplicationContext.refresh();
 36     * 第一种方式只会重命名@ComponentScan扫描到的注解类
 37     * 第二种只有是初始化的注解类就会被重命名
 38     * 列如第一种方式不会重命名 @Configuration 注解的bean名称,而第二种就会重命名 @Configuration 注解的Bean名称
 39     */
 40    Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
 41 
 42    /**
 43     * 用于解析@Scope注解,可通过 AnnotationConfigApplicationContext 的 setScopeMetadataResolver 方法重新设定处理类
 44     * ScopeMetadataResolver scopeMetadataResolver = definition -> new ScopeMetadata();  这里只是new了一个对象作为演示,没有做实际的逻辑操作
 45     * AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
 46     * annotationConfigApplicationContext.setScopeMetadataResolver(scopeMetadataResolver);
 47 
 48     * annotationConfigApplicationContext.register(MainConfig2.class);
 49     * annotationConfigApplicationContext.refresh();
 50     * 也可以通过@ComponentScan 的 scopeResolver 属性设置
 51     *@ComponentScan(value = "spring.annotation.componentscan",scopeResolver = MyAnnotationScopeMetadataResolver.class)
 52     */
 53    Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
 54 
 55    /**
 56     * 用来设置类的代理模式
 57     */
 58    ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
 59 
 60    /**
 61     * 扫描路径 如 resourcePattern = "**/*.class"
 62     * 使用  includeFilters 和 excludeFilters 会更灵活
 63     */
 64    String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;
 65 
 66    /**
 67     * 指示是否应启用对带有{@code @Component},{@ code @Repository},
 68     * {@ code @Service}或{@code @Controller}注释的类的自动检测。
 69     */
 70    boolean useDefaultFilters() default true;
 71 
 72    /**
 73     * 对被扫描的包或类进行过滤,若符合条件,不论组件上是否有注解,Bean对象都将被创建
 74     * @ComponentScan(value = "spring.annotation.componentscan",includeFilters = {
 75     *     @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class, Service.class}),
 76     *     @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {SchoolDao.class}),
 77     *     @ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class}),
 78     *     @ComponentScan.Filter(type = FilterType.ASPECTJ, pattern = "spring.annotation..*"),
 79     *     @ComponentScan.Filter(type = FilterType.REGEX, pattern = "^[A-Za-z.]+Dao$")
 80     * },useDefaultFilters = false)
 81     * useDefaultFilters 必须设为 false
 82     */
 83    Filter[] includeFilters() default {};
 84 
 85    /**
 86     * 指定哪些类型不适合进行组件扫描。
 87     * 用法同 includeFilters 一样
 88     */
 89    Filter[] excludeFilters() default {};
 90 
 91    /**
 92     * 指定是否应注册扫描的Bean以进行延迟初始化。
 93     * @ComponentScan(value = "spring.annotation.componentscan",lazyInit = true)
 94     */
 95    boolean lazyInit() default false;
 96 
 97 
 98    /**
 99     * 用于 includeFilters 或 excludeFilters 的类型筛选器
100     */
101    @Retention(RetentionPolicy.RUNTIME)
102    @Target({})
103    @interface Filter {
104 
105       /**
106        * 要使用的过滤器类型,默认为 ANNOTATION 注解类型
107        * @ComponentScan.Filter(type = FilterType.ANNOTATION, classes = {Controller.class, Service.class})
108        */
109       FilterType type() default FilterType.ANNOTATION;
110 
111       /**
112        * 过滤器的参数,参数必须为class数组,单个参数可以不加大括号
113        * 只能用于 ANNOTATION 、ASSIGNABLE_TYPE 、CUSTOM 这三个类型
114        * @ComponentScan.Filter(type = FilterType.ANNOTATION, value = {Controller.class, Service.class})
115        * @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {SchoolDao.class})
116        * @ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class})
117        */
118       @AliasFor("classes")
119       Class<?>[] value() default {};
120 
121       /**
122        * 作用同上面的 value 相同
123        * ANNOTATION 参数为注解类,如  Controller.class, Service.class, Repository.class
124        * ASSIGNABLE_TYPE 参数为类,如 SchoolDao.class
125        * CUSTOM  参数为实现 TypeFilter 接口的类 ,如 MyTypeFilter.class
126        * MyTypeFilter 同时还能实现 EnvironmentAware,BeanFactoryAware,BeanClassLoaderAware,ResourceLoaderAware 这四个接口
127        * EnvironmentAware
128        * 此方法用来接收 Environment 数据 ,主要为程序的运行环境,Environment 接口继承自 PropertyResolver 接口,详细内容在下方
129        * @Override
130        * public void setEnvironment(Environment environment) {
131        *    String property = environment.getProperty("os.name");
132        * }
133        * 
134        * BeanFactoryAware
135        * BeanFactory Bean容器的根接口,用于操作容器,如获取bean的别名、类型、实例、是否单例的数据
136        * @Override
137        * public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
138        *     Object bean = beanFactory.getBean("BeanName")
139        * }
140        * 
141        * BeanClassLoaderAware
142        * ClassLoader 是类加载器,在此方法里只能获取资源和设置加载器状态
143        * @Override
144        * public void setBeanClassLoader(ClassLoader classLoader) {
145        *     ClassLoader parent = classLoader.getParent();
146        * }
147        * 
148        * ResourceLoaderAware
149        * ResourceLoader 用于获取类加载器和根据路径获取资源
150        * public void setResourceLoader(ResourceLoader resourceLoader) {
151        *     ClassLoader classLoader = resourceLoader.getClassLoader();
152        * }
153        */
154       @AliasFor("value")
155       Class<?>[] classes() default {};
156 
157       /**
158        * 这个参数是 classes 或 value 的替代参数,主要用于 ASPECTJ 类型和  REGEX 类型
159        * ASPECTJ  为 ASPECTJ 表达式
160        * @ComponentScan.Filter(type = FilterType.ASPECTJ, pattern = "spring.annotation..*")
161        * REGEX  参数为 正则表达式
162        * @ComponentScan.Filter(type = FilterType.REGEX, pattern = "^[A-Za-z.]+Dao$")
163        */
164       String[] pattern() default {};
165 
166    }
167 
168 }

Environment

 

 1 public interface Environment extends PropertyResolver {
 2  
 3    /**
 4     * 这个方法用来取到 ConfigurableEnvironment.setActiveProfiles(String...) 设置的值,这个方法搭配 @Profile 注解使用
 5     * 如 :
 6     * @Bean()
 7     * @Profile("dev")
 8     * public Student student() {
 9     *  System.out.println("createStudent");
10     *    return new Student("王五", 18);
11     * }
12     *
13     * @Test
14     * public void testImport(){
15     * AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext();
16     * ConfigurableEnvironment environment = annotationConfigApplicationContext.getEnvironment();
17     * environment.setActiveProfiles("dev");
18     * annotationConfigApplicationContext.register(MainConfig2.class);
19     * annotationConfigApplicationContext.refresh();
20     *  String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
21     * for (String s : beanDefinitionNames) {
22     *       System.out.println(s);
23     *    }
24     *  }
25     * 
26     * @Profile("dev")
27     * environment.setActiveProfiles("dev");
28     * 当 setActiveProfiles 里的值在 @Profile 中存在,此时就会注册这个Bean
29     * 而 getActiveProfiles 取到的也是 setActiveProfiles 中的值
30     */
31    String[] getActiveProfiles();
32 
33    /**
34     * 未明确设置有效配置文件时,返回默认有效的配置文件集
35     */
36    String[] getDefaultProfiles();
37 
38    /**
39     * 返回一个或多个给定的配置文件是否处于活动状态,或者在没有显式活动
40     * 配置文件的情况下,返回一个或多个给定的配置文件是否包含在默认配置
41     * 文件集中。 如果个人资料以“!”开头 逻辑取反,即如果给定的配置文件未
42     * 激活,则该方法将返回true。 例如,如果配置文件“ p1”处于活动状态或“ 
43     * p2”处于非活动状态,则env.acceptsProfiles(“ p1”,“!p2”)将返回true。
44     * 不推荐使用
45     */
46    @Deprecated
47    boolean acceptsProfiles(String... profiles);
48 
49    /**
50     * Return whether the {@linkplain #getActiveProfiles() active profiles}
51     * 返回活动概要文件是否 与给定Profiles谓词匹配。,不推荐使用
52     */
53    boolean acceptsProfiles(Profiles profiles);
54 
55 }

 

 

PropertyResolver

 

 1 public interface PropertyResolver {
 2 
 3    /**
 4     * 判断给定键的值是否为 null
 5     */
 6    boolean containsProperty(String key);
 7 
 8    /**
 9     * 返回给定键的值,如果不存在就返回 null,可获取配置文件中的数据
10     * @param key 键
11     */
12    @Nullable
13    String getProperty(String key);
14 
15    /**
16     * 返回给定键的值,值若为 null 则返回默认值
17     * @param key 键
18     * @param defaultValue 指定返回的默认值
19     */
20    String getProperty(String key, String defaultValue);
21 
22    /**
23     * 返回给定键的值,如果不存在就返回 null,需要指定返回的类型
24     * @param key 键
25     * @param targetType 指定返回的类型,不要用基础类型,用包装类
26     */
27    @Nullable
28    <T> T getProperty(String key, Class<T> targetType);
29 
30    /**
31     * 返回给定键的值,如果不存在就返回默认值,需要指定返回的类型
32     * @param key 键
33     * @param targetType 指定的返回类型
34     * @param defaultValue 指定的返回默认值
35     *
36 */ 37 <T> T getProperty(String key, Class<T> targetType, T defaultValue); 38 39 /** 40 * 返回给定键的值,如果不存在则抛出 IllegalStateException 异常 41 */ 42 String getRequiredProperty(String key) throws IllegalStateException; 43 44 /** 45 * 返回给定键的值,如果不存在则抛出 IllegalStateException 异常,需要指定返回类型 46 * targetType 指定返回的类型 47 */ 48 <T> T getRequiredProperty(String key, Class<T> targetType) throws IllegalStateException; 49 50 /** 51 * 在给定的文本中解析$ {...}占位符,将其替换为由 getProperty 解析的相应属性值。 没有默认值的无法解析的占位符将被忽略,并按原样传递。 52 * 比如 String str = environment.resolvePlaceholders("这是${os.name}系统"); 53 * 返回值为 这是Windows 10系统 54 * @param text 需要被被解析的文本,若文本为 null 则会抛出IllegalStateException 异常 55 */ 56 String resolvePlaceholders(String text); 57 58 /** 59 * 在给定的文本中解析$ {...}占位符,将其替换为 getProperty 解析的相应属性值。 没有默认值的无法解析的占位符将导致引发IllegalArgumentException。 60 * 比如 String s = environment.resolveRequiredPlaceholders("${}"); 61 * 就会抛出 IllegalArgumentException异常 62 */ 63 String resolveRequiredPlaceholders(String text) throws IllegalArgumentException; 64 65 }

 

posted @ 2019-12-23 11:57  高龄码农丹  阅读(10768)  评论(0编辑  收藏  举报