Author 罗先生
本文是IOC系列的第五篇,往期回顾:
ImportAware是什么
实现了这个接口的类,在其setImportMetadata方法中可以拿到某个bean上的注解上的属性值。
ImportAware例子-动态注入数据源:
先来个注解,让数据源的注入成为可开关,就和AOP的@EnableAspectJAutoProxy类似
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Import({DynamicDateSourceImportAwareBeanPostProcessor.class})
public @interface EnnableDbConfig {
String userName() default "";
String password() default "";
String url() default "";
}
值得注意的是需要注入@Import下面自定义的DynamicDateSourceImportAware 类
为什么要Import进来?而不是直接扫描?
如果是我们自己的项目自己写的当然可以扫描进来,但是如果是第三方的包,就需要用Import进来了。可看第三部分实际应用RedissonHttpSessionConfiguration 就是需要Import进项目里的,不然setImportMetadata就不会执行了
再来一个自定义实现ImportAware 接口的核心类,实现数据源的动态注入,核心方法在于setImportMetadata
@Configuration
public class DynamicDateSourceImportAware implements ImportAware {
private String userName;
private String password;
private String url;
public void setImportMetadata(AnnotationMetadata annotationMetadata) {
Map<String, Object> map = annotationMetadata.getAnnotationAttributes(EnnableDbConfig.class.getName());
AnnotationAttributes attrs = AnnotationAttributes.fromMap(map);
this.userName = attrs.getString("userName");
this.password = attrs.getString("password");
this.url = attrs.getString("url");
}
@Bean
public DataSource dataSource() {
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
driverManagerDataSource.setPassword(password);
driverManagerDataSource.setUsername(userName);
driverManagerDataSource.setUrl(url);
driverManagerDataSource.setDriverClassName("com.mysql.jdbc.Driver");
return driverManagerDataSource;
}
}
值得注意的是DynamicDateSourceImportAware 类必须用@Configuration注解标注,否则setImportMetadata不会执行,也就拿不到数据源信息了
最后则是使用
@Configuration
@EnableAspectJAutoProxy
@EnnableDbConfig(userName = "root", password = "root", url = "jdbc:mysql://localhost:3306/test")
@ComponentScan("cn.study.lqw")
public class Appconfig {
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
}
这样Spring就存在一个你想要的数据源了,不信的小伙伴可以自己测试
ImportAware实际应用:
Spring当中有一个@EnableRedissonHttpSession注解,其上可指定key和对应的key的过期时间,原理就是ImportAware接口,源码如下:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Import({RedissonHttpSessionConfiguration.class})
@Configuration
public @interface EnableRedissonHttpSession {
int maxInactiveIntervalInSeconds() default 1800;
String keyPrefix() default "";
}
@Configuration
public class RedissonHttpSessionConfiguration extends SpringHttpSessionConfiguration implements ImportAware {
private Integer maxInactiveIntervalInSeconds;
private String keyPrefix;
...
public void setImportMetadata(AnnotationMetadata importMetadata) {
Map<String, Object> map = importMetadata.getAnnotationAttributes(EnableRedissonHttpSession.class.getName());
AnnotationAttributes attrs = AnnotationAttributes.fromMap(map);
this.keyPrefix = attrs.getString("keyPrefix");
this.maxInactiveIntervalInSeconds = (Integer)attrs.getNumber("maxInactiveIntervalInSeconds");
}
}
看懂了我的代码,这个代码就很好看懂了。。 和我几乎是一样的