@Import使用
@Import:导入第三方jar包中的组件。
@Lookup:它的作用是单实例组件获取非单例bean(每次获取都是一个新的),如果不适用lookup注解,那么单例beanA引用一个beanB,每次getB,都只会拿到一个B(不管执行多少次,都只能拿到第一次的B–这时候,你以为B是单例的。)。避免这种情况就使用lookup。
首先在spring中注册一个组件的流程:
先定义一个person类
public class Person {
private String name;
public Person() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" + "name='" + name + '\'' + '}';
}
}
配置类mainconfig
@Configuration//这是一个配置类,类似xml那种配置
public class MainConfig {
@Bean
public Person person(){
Person person = new Person();
person.setName("lisi");
return person;
}
}
public class Client {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(
MainConfig.class);
Person person = context.getBean( Person.class);
System.out.println(person.toString());
}
}
输出Person{name='lisi'}
使用import注解的话
@Configuration
@Import({ Person.class })
public class MainConfig {
// @Bean
// public Person person(){
// Person person = new Person();
// person.setName("lisi");
// return person;
// }
}
调用client–main方法,输出Person{name=null}
使用ImportBeanDefinitionRegistrar
@Configuration
@Import({ MainConfig.MyImport.class })
public class MainConfig {
/**
* BeanDefinitionRegistry bean定义信息
*/
static class MyImport implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
BeanDefinitionRegistry registry) {
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition();
rootBeanDefinition.setBeanClass(Cat.class);
registry.registerBeanDefinition("mycat",rootBeanDefinition);
}
}
}
public class Client {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(
MainConfig.class);
String[] beanDefinitionNames = context.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
}
输出:mycat mainConfig,证明rootBeanDefinition也将mycat变成了组件。
@Lookup注解使用。
先将bean的作用域设置为prototype(原型模式,只要对它请求一次,就会返回一个新的bean实例。)
@Component
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class Cat {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Client {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(
MainConfig.class);
Cat bean = context.getBean(Cat.class);
Cat bean1 = context.getBean(Cat.class);
System.out.println(bean == bean1);
}
}
返回false。证明两次bean不是同一个,也就是调用两次,生成两个bean实例。
那在单例person类下定义一个原型的cat类。会是怎么样的?
@Component
public class Person {
@Autowired
private Cat cat;
@Lookup
public Cat getCat() {
return cat;
}
public void setCat(Cat cat) {
this.cat = cat;
}
}
public class Client {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(
MainConfig.class);
Person bean1 = context.getBean(Person.class);
Person bean2 = context.getBean(Person.class);
Cat cat1 = bean1.getCat();
Cat cat2 = bean2.getCat();
System.out.println(cat1 == cat2);
}
}
返回false。
注意:Lookup只能在方法上,且不能在@Bean里,必须是在get方法上,set不生效。