Java类和注解代替xml配置
@Configuration:
1.代替beans
2.<beans>
<bean id="user" class="com.example.User />
</beans>
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
变为:
@Configuration
public class Config {
@Bean("user")
public User user() {
return new User();
}
}
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
@Bean:
1.相当于bean元素
2.<bean id="user" class="com.example.User" scope="prototype" init-method="init"
destroy-method="destroy" lazy-init="true">
<constructor-arg ref="hello"/>
</bean>
变为:
@Configuration
public class Config {
@Bean(name="user", initMethod="init", destroyMethod="destroy")
@Scope("prototype")
@Lazy
public User user() {
return new User();
}
}
bean的默认值为方法名
3.@Bean依赖注入:直接在构造函数中传参
1).@Configuration
public class Config {
@Bean("user")
@Scope("prototype")
public User user() {
/*return new User(hello()); 此时如果hello为单例,则此处传入的参数也是同一实例*/
return new User(new Hello()); //若hello为单例,new Hello()得到的时不同实例
}
@Bean("hello")
public Hello hello() {
return new Hello();
}
}
2).参数自动注入:
. @Bean("user")
public User user(Hello hello) {..}
首先按照byType注入,如果有多个相同类型的bean,则寻找与id与参数名相同的bean,没有则报错
. @Bean("user")
public User user(@Qualifier("hello") Hello hello){..}
寻找id为@Qualifier指定值的bean
. @Bean("user")
public User user(Hello hello) {..}
@Primary
@Bean("hello")
public Hello hello(){..}
@Bean("hello1")
public Hello hello1(){..}
优先匹配使用@Primary注解的bean
@ComponentScan:
1.<context:component-scan base-package="包名"/>
变为:
@Configuration
@ComponentScan(basePackages="包名")
public class Config {..}
默认值是扫描该类所在的包以及子包下的所有类
可以与@Component一起用
2.组件注册时的过滤条件:
1.value:指定要扫描的包
2.excludeFilters=Filter[]:指定扫描包的时候按照什么规则排除哪些组件
3.includeFilters=Filter[]:指定扫描包的时候要包含哪些组件,需将useDefaultFilters置false
4.FilterType.ANNOTATION:按照注解
FilterType.ASSIGNABLE_TYPE:按照指定的类型
FilterType.REGEX:使用正则指定
FilterType.CUSTOM:使用自定义规则
示例:
@ComponentScan(value="com.example", includeFilters={
@Component.Filter(type=FilterType.ANNOTATION, classes={Controller.class}),
@ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes={BookService.class},
useDefaultFilters=false }
扫描com.example包及子包下的类,只需要 使用了@Controller注解的类和 BookService类
@Condition:
1.满足条件才注册bean
2.首先需要有个类实现Condition接口
public class MyCondition implements Condition {
@Override
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {}
}
@Condition({MyCondition.class})
@Bean("user")
public User user(){..}
当mathes方法返回true时,才注册bean
?@Import:
1.导入其他配置类或组件类(@Component)
2.@Configuration
@Import({类1, 类2...})
public class Config {}
3.ImportSelector: 定义逻辑来决定导入哪些类
1).首先要有个类实现ImportSelector接口
2). public MyImportSelector implements ImportSelector {
@Override
String[] selectImports(AnnotationMetadata importingClassMetadata){
return new String[]{"xx", "xx" ...}; //返回要导入的类的全限定名
}
}
3).@Configuration
@Import(MyImportSelector.class)
将导入selectImports方法返回的名称的类
4.@ImportResource: 导入xml配置文件
如 @ImportResource("classpath:beans.xml")
FactoryBean:
public class ColorFactoryBean implements FactoryBean<Color> {
// 返回一个Color对象,这个对象会添加到容器中
@Override
public Color getObject() throws Exception {
System.out.println("ColorFactoryBean.getObject");
return new Color();
}
@Override
public Class<?> getObjectType() {
return Color.class;
}
// 是否是单例: true, 在容器中只会保留一份
@Override
public boolean isSingleton() {
return true;
}
}
@Configuration
public class MainConfig{
// 实际返回的是getObject()方法返回的对象
@Bean
public ColorFactoryBean colorFactoryBean(){
return new ColorFactoryBean();
}
}
|