首先,@Lookup注解的作用是单实例组件依赖非单例组件。
依赖的组件为多实例就不能是@Autowired- 在被依赖的类上标明@Lookup
前提补充:组件的作用域有两种,单例和多实例
@Scope 声明组件的作用范围 (SCOPE_PROTOTYPE原型【获取的克隆对象】,SCOPE_SINGLETON单例)
被单例声明的再ioc容器中事中只会被创建一个。
接下来举个例子来说明@Lookup的用途
在之前的环境下,新增一个Cat类,Person属性 包含了Cat 实例,
假设一个人可以有多只猫,但是这个屋子中人只有一个;即我想让person做成单实例,cat是多实例
人是单实例,但是从人身上获取猫,每一次都是一个新的猫。
注意:1.@Lookup对@Bean注册的组件不生效。
2.@Lookup标在多实例组件的get方法上
3.单实例组件依赖的原型方法属性上去掉@Autowired注解
Lookup注解:
@Scope(value = "prototype")
@Component --这个组件的使用在配置列中需要添加包扫描
public class Cat {
private String name;
@Lookup --标在get方法,看到cat是原型,所以找得时候就创建副本,且对@Bean注册的Person,不生效 public String getName() { return name; } public void setName(String name) { this.name = name; } }
@Compont //因为@Bean 创建的@Bean实例不能和@Lookup一起使用
public class Person {
private String name;
//为了让cat走原型装配,这里就要把自动装配注掉,在cat的get方法上标@Lookup
//@Autowired 因为person是单实例的,所以只要从容器中拿到person点出来的cat,在自动装配的情况下永远是 原型中第一个构造person的cat
private Cat cat;
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
配置类修改
//@Import({Person.class, MainConfig.MyImportRegistrar.class}) @ComponentScan("com.tomasfeng.spring") //扫描包下的@Compont注解和变体 @Configuration//这是一个代替xml的配置类
public class MainConfig { //@Bean //Lookup,对于@Bean返回的对象不生效,要在定义Person类上加@Compont public Person person(){ Person person = new Person(); person.setName("TomasByConfiguration"); return person; }