Spring 註解驅動(一)基本使用規則
阿新 • • 發佈:2018-12-31
Spring 註解驅動(一)基本使用規則
Spring 系列目錄(https://www.cnblogs.com/binarylei/p/10198698.html)
一、基本使用
@Configuration @ComponentScan(basePackages = "com.github.binarylei", excludeFilters = {@Filter(type = FilterType.ANNOTATION, classes = {Controller.class})} ) @Lazy(false) public class AnnnotationConfig { // Scope 可取四個值:SCOPE_SINGLETON、SCOPE_PROTOTYPE、SCOPE_SESSION、SCOPE_REQUEST @Bean @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) public User user() { return new User(); } }
啟動測試:
public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnnnotationConfig.class); // AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); // context.register(AnnnotationConfig.class); // context.refresh(); User user = context.getBean(User.class); }
二、@ComponentScan
@Configuration @ComponentScan(basePackages = "com.github.binarylei", excludeFilters = { @Filter(type = FilterType.ANNOTATION, classes = {Controller.class}), @Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {User.class}), @Filter(type = FilterType.CUSTOM,classes = MyFilter.class) }, useDefaultFilters = false ) public class AnnnotationConfig { }
自定義的包掃描如下:
public class MyFilter implements TypeFilter {
/**
* @param metadataReader 當前類的資訊
* @param metadataReaderFactory 獲取其他類的資訊
*/
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException {
// 1. 當前類的註解資訊
AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();
// 2. 當前類的資訊
ClassMetadata classMetadata = metadataReader.getClassMetadata();
// 3. 當前類的資源資訊(類路徑)
Resource resource = metadataReader.getResource();
return true;
}
}
三、@Conditional
@Bean
@Conditional(MyCondition.class)
public User user() {
return new User();
}
// 條件裝配
public class MyCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 1. IOC 容器
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// 2. 類載入器
ClassLoader classLoader = context.getClassLoader();
// 3. 環境變數
Environment environment = context.getEnvironment();
// 4. 可以向容器中註冊 BeanDefinition
BeanDefinitionRegistry registry = context.getRegistry();
return environment.getProperty("os.name").contains("Windows");
}
}
四、@Import
給容器中註冊元件有以下方式:
- @Bean
- 包掃描(@ComponentScan) + 註解(@Componet/@Repository/@Service/@Controller)
- @Import
- @Import({User.class}) 匯入單個元件
- @Import({User.class, MyImportSelector.class}) MyImportSelector 批量匯入元件
- @Import({User.class, MyImportBeanDefinitionRegistrar.class}) MyImportBeanDefinitionRegistrar 批量匯入元件
- FactoryBean
@Import({User.class, MyImportSelector.class})
@Import({User.class, MyImportBeanDefinitionRegistrar.class})
public class AnnnotationConfig {
}
// 返回類名的全定限名稱
public class MyImportSelector implements ImportSelector {
/**
* @param importingClassMetadata 獲取標註 @Import 註解的類所有註解資訊(不僅僅是 @Import)
*/
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
// 不要返回 null,否則會報空指標異常
return new String[]{User.class.getName()};
}
}
// 使用 BeanDefinitionRegistry 註冊
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
/**
* @param importingClassMetadata 獲取標註 @Import 註解的類所有註解資訊(不僅僅是 @Import)
* @param registry 向容器中註冊 BeanDefinition
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
boolean definition1 = registry.containsBeanDefinition("red");
boolean definition2 = registry.containsBeanDefinition("blue");
if (definition1 && definition2) {
RootBeanDefinition beanDefinition = new RootBeanDefinition(User.class);
registry.registerBeanDefinition("user", beanDefinition);
}
}
}
五、Bean 的生命週期
- @Bean(initMethod = "init", destroyMethod = "destroy")
- 實現 InitializingBean, DisposableBean 介面
每天用心記錄一點點。內容也許不重要,但習慣很重要!