本次主要整理四个注解 @ComponentScan、@Scope、@Conditional、@Import
1. @ComponentScan(value = "com.xiaoguo") 报扫描注解: 扫描该路径下的@controller @component @service 等等注解并将其交给spring容器管理。可以选择只扫描那些组件或是排除那些组件: includeFilters=Filter[]:指定只包含的组件
excludeFilters=Filter[]:指定需要排除的组件;
注解:
1 @ComponentScan(value = "com.xiaoguo.annotation", excludeFilters = { 2 @ComponentScan.Filter(type = FilterType.CUSTOM, classes = {MyTypeFilter.class}) 3 })
自定义过滤类:
1 package com.xiaoguo.annotation.filter; 2 3 import com.xiaoguo.annotation.beans.Car; 4 import org.springframework.core.io.Resource; 5 import org.springframework.core.type.AnnotationMetadata; 6 import org.springframework.core.type.ClassMetadata; 7 import org.springframework.core.type.classreading.MetadataReader; 8 import org.springframework.core.type.classreading.MetadataReaderFactory; 9 import org.springframework.core.type.filter.TypeFilter; 10 11 import java.io.IOException; 12 13 /** 14 * @author xiaoguo 15 * @date 2019-10-14 下午 9:11 16 */ 17 public class MyTypeFilter implements TypeFilter { 18 19 20 21 @Override 22 public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory) throws IOException { 23 //获取当前正在扫描的类的类信息 24 ClassMetadata classMetadata = metadataReader.getClassMetadata(); 25 String className = classMetadata.getClassName(); 26 Class<?> forName = null; 27 try { 28 forName = Class.forName(className); 29 if (Car.class.isAssignableFrom(forName)) { 30 // true就加载到IOC容器 31 return true; 32 } 33 } catch (ClassNotFoundException e) { 34 e.printStackTrace(); 35 } 36 return false; 37 } 38 }
2. @Scope("prototype") 此注解表示交给容器管理的对象为多例模式,不加默认为但例模式,加此注解每次从容器获取对象都是新new的对象。
3. @Conditional({WindowsCondition.class}) 按照一定的条件满足条件的则注册bean到容器中
注解:
1 @Conditional({LinuxCondition.class}) 2 @Bean("linux") 3 public Person person03() { 4 return new Person("linux", 25); 5 }
自定义条件类:
1 package com.xiaoguo.annotation.condition; 2 3 import org.springframework.context.annotation.Condition; 4 import org.springframework.context.annotation.ConditionContext; 5 import org.springframework.core.env.Environment; 6 import org.springframework.core.type.AnnotatedTypeMetadata; 7 8 /** 9 * @author xiaoguo 10 * @date 2019-10-11 下午 8:12 11 */ 12 public class LinuxCondition implements Condition { 13 14 15 16 @Override 17 public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { 18 19 //3.获取到当前环境信息 20 Environment environment = context.getEnvironment(); 21 22 String property = environment.getProperty("os.name"); 23 if (property.contains("linux")) { 24 //true 注入bean 25 return true; 26 } 27 return false; 28 } 29 }
4. @Import({Car.class}) 快速将Car导入到spring容器中
ImportSelector 注册类到容器中:
1 @Import({MyImportSelector.class}) 2 3 4 5 6 public class MyImportSelector implements ImportSelector { 7 8 9 /** 10 * 返回值就是导入容器中的组件全类名 11 * 12 * @param importingClassMetadata 13 * @return 14 */ 15 @Override 16 public String[] selectImports(AnnotationMetadata importingClassMetadata) { 17 return new String[]{"com.xiaoguo.annotation.beans.Red"}; 18 } 19 }
ImportBeanDefinitionRegistrar与上同理:
1 public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { 2 3 /** 4 * 5 * @param importingClassMetadata 当前类的注解信息 6 * @param registry BeanDefinition注册类 7 */ 8 @Override 9 public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { 10 boolean tf = registry.containsBeanDefinition("com.xiaoguo.annotation.beans.Red"); 11 if (tf) { 12 RootBeanDefinition beanDefinition = new RootBeanDefinition(XiaoGuo.class); 13 registry.registerBeanDefinition("xiaoguo", beanDefinition); 14 } 15 } 16 }