spring注解驱动开发(二)
@Import的使用
目前我们知道的往ioc容器中注册组件的方式有两种
- 在类上标注@component、@Service、@Controller、@Repository,然后通过@ComponentScan的方式扫描到ioc容器中
- 在配置类中需要注册到ioc容器的组件使用@Bean主机的方式
出了上面的方法,那么我们再介绍几种方法
@Import可以实现快速注册组件的目的
@Import({MyImportSelector.class})
然而在ioc中的id是该类的全类名
FactoryBean接口可以实现注册组件的目的
我们可以创建一个类实现FactoryBean接口1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public class PersonFactoryBean implements FactoryBean<Person>{
//返回对象会加载到ioc容器中
public Person getObject() throws Exception {
// TODO Auto-generated method stub
System.out.println("成功调用");
return new Person();
}
//指定类型
public Class<?> getObjectType() {
// TODO Auto-generated method stub
return Person.class;
}
//指定是否是单例模式
public boolean isSingleton() {
// TODO Auto-generated method stub
return true;
}
}
然后我们可以测试1
2
3
4
5AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
Object bean = context.getBean("personFactoryBean");
System.out.println(bean.getClass());//打印出来的是class cn.itcast.pojo.Person
Object bean1 = context.getBean("&personFactoryBean");
System.out.println(bean1.getClass());//打印出来的是class cn.itcast.config.PersonFactoryBean
注:上面在获取bean的时候,有一个符号
&
,通过加上这个符号可以获得注册组件自己
ImportSelector接口可以实现注册组件的目的
我们把要注册到ioc容器中组件的全类名放在返回的数组中1
2
3
4
5
6
7public class MyImportSelector implements ImportSelector{
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[] {"cn.itcast.pojo.Role","cn.itcast.pojo.Dog"};
}
}
记得把MyImportSelector注册到ioc容器中,这里我们采用快速注入的方式@Import({MyImportSelector.class})
我们可以一次注册多个组件到容器中
ImportBeanDefinitionRegistrar接口可以实现注册组件的目的
1 |
|
@Bean中的initMethod、destroyMethod
原先我们使用xml配置的方式表示为:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20public class Role {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void init() {
System.out.println("容器初始化");
}
public void destory() {
System.out.println("容器被销毁");
}
}
1 | <bean id="role" class="cn.itcast.pojo.Role" init-method="init" destroy-method="destory"> |
在@Bean中有两个属性1
2
3
4"init",destroyMethod="destory") (initMethod=
public Role role() {
return new Role();
}
注:在销毁的时候,单实例容器会销毁,但是多实例,容器不负责销毁,所以在多实例下销毁方法不调用
在初始化的时候,单实例容器运行时,会调用初始化(init)方法,多实例在调用对象的时候创建(执行init的方法)
@Value、@PropertySource的使用
以前我们使用下面方式给组件赋值1
2
3<bean id="dog" class="cn.itcast.pojo.Dog">
<property name="name" value="旺财"></property>
</bean>
在注解版中我们可以使用1
2
3
4"旺财") (
private String name;
"#{2*3}") (
private String nickName;
当然这种硬编码不太好,所以我们可以加载配置文件中的值,那么引入@PropertySource实现引入配置文件
然后使用属性占位符的方式得到1
2"${dog.name}") (
private String name;
当然你也可以使用SPEL表达式得到。1
2 "#{systemProperties['dog.name']}") (
private String name;
@Autowired、@Qualifier、@Primary注解的使用
@Autowired用作组件的自动装配,装配的规则是
- 首先按照组件的类型从ioc容器中查找,查找到装配完成
- 如果遇到多个同类型的组件,那么会使用属性名作为查找ioc容器组件的id
- 如果没有查到到,会报错!但是我们又不想让它报错,那么我们可以使用
@Autowired(required=false)
当然我们也可以自己指定需要查找组件的id,用@Qualifier("indexService1")
,这样我们就可以去ioc容器中查找id是indexService1的组件
同时呢,spring也给我们提供了@Primary,意思是要找此类型的组件,首选此组件1
2
3
4
5
public IndexService indexService1() {
return new IndexService();
}
注:@Primary注解使用的时候,就不要使用@Qualifier注解了
spring也支持@Resource(JSR250)和@Inject(JSR330),这些都是java规范
@Resource默认按照属性的名称作为组件的id去ioc容器查找,当然我们也可以使用@Resource(name=’indexDao1’)设置
@Inject需要导入javax.inject的包,在使用上和@Autowired一样
@Autowired可以使用在构造器,方法,属性上面、参数位置,如果组件只有一个有参构造器,参数位置的@Autowired可以省略,还有@Bean中的参数,也不用写@Autowired,都可以从容器中自动装配
@Profile注解的使用
Spring为我们提供的可以根据当前环境,动态的激活和切换一系列组件的功能
默认的profile是default
我们在某个组件上面加上@Profile('test')
,一旦加上之后,就是当环境激活的时候,对应的bean才可以注册到容器中
那么如何激活呢
- 在运行到时候,设置命令行参数的方式 -Dspring.profiles.active=test
- 可以借助applicationContext方式激活环境,例如:
1
2
3
4
5
6
7AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
//设置需要激活的环境
context.getEnvironment().setActiveProfiles("test","dev");
//注册主配置类
context.register(MyConfig.class);
//启动刷新容器
context.refresh();