茂展的分享博客

spring注解驱动开发(二)

spring注解驱动开发(二)

@Import的使用

目前我们知道的往ioc容器中注册组件的方式有两种

  1. 在类上标注@component、@Service、@Controller、@Repository,然后通过@ComponentScan的方式扫描到ioc容器中
  2. 在配置类中需要注册到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
20
public 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
5
AnnotationConfigApplicationContext 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
7
public 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15

public class MyImportBeanDefinitionRegister implements ImportBeanDefinitionRegistrar{

public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//首先判断ioc中是否有role这个组件,如果有的话,就注册bean
boolean flag = registry.containsBeanDefinition("cn.itcast.pojo.Role");
if(flag) {
//注册person组件
RootBeanDefinition beanDefinition = new RootBeanDefinition(Person.class);
registry.registerBeanDefinition("person",beanDefinition);

}
}

}

@Bean中的initMethod、destroyMethod

原先我们使用xml配置的方式表示为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public 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
2
3
<bean id="role" class="cn.itcast.pojo.Role" init-method="init" destroy-method="destory">
<property name="name" value="bean生命周期"></property>
</bean>

在@Bean中有两个属性

1
2
3
4
@Bean(initMethod="init",destroyMethod="destory")
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
@Value("旺财")
private String name;
@Value("#{2*3}")
private String nickName;

当然这种硬编码不太好,所以我们可以加载配置文件中的值,那么引入@PropertySource实现引入配置文件
然后使用属性占位符的方式得到

1
2
@Value("${dog.name}")
private String name;

当然你也可以使用SPEL表达式得到。

1
2
   @Value("#{systemProperties['dog.name']}")
private String name;

@Autowired、@Qualifier、@Primary注解的使用

@Autowired用作组件的自动装配,装配的规则是

  1. 首先按照组件的类型从ioc容器中查找,查找到装配完成
  2. 如果遇到多个同类型的组件,那么会使用属性名作为查找ioc容器组件的id
  3. 如果没有查到到,会报错!但是我们又不想让它报错,那么我们可以使用@Autowired(required=false)
    当然我们也可以自己指定需要查找组件的id,用@Qualifier("indexService1"),这样我们就可以去ioc容器中查找id是indexService1的组件
    同时呢,spring也给我们提供了@Primary,意思是要找此类型的组件,首选此组件
    1
    2
    3
    4
    5
    @Primary
    @Bean
    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
    7
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    //设置需要激活的环境
    context.getEnvironment().setActiveProfiles("test","dev");
    //注册主配置类
    context.register(MyConfig.class);
    //启动刷新容器
    context.refresh();
------本文结束感谢阅读------
🐶 您的支持将鼓励我继续创作 🐶