-
概述
@Lookup用于单例组件引用prototype组件。单例组件使用@Autowired方式注入prototype组件时,被引入prototype组件也会变成单例的。@Lookup可以保证被引入的组件保持prototype模式。
-
使用@Autowired注入
-
创建一个配置类指定包扫描路径
package com.hl.config;
import com.hl.bean.Car;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.hl")
public class MainConfig {
/*@Bean
public Car getCar(){
Car car = new Car();
car.setName("红旗");
return car;
}*/
}
-
创建一个Car类使用@Autowired引入Seat
package com.hl.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Car {
private String name;
@Autowired
private Seat seat;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Seat getSeat() {
return seat;
}
public void setSeat(Seat seat) {
this.seat = seat;
}
}
package com.hl.bean;
import org.springframework.stereotype.Component;
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Component
public class Seat {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
-
测试
package com.hl;
import com.hl.bean.Car;
import com.hl.bean.Seat;
import com.hl.config.MainConfig;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(MainConfig.class);
Car car = (Car) context.getBean("car");
Seat seat = car.getSeat();
Car car1 = (Car) context.getBean("car");
Seat seat1 = car1.getSeat();
System.out.println(seat == seat1);
}
}
从容器中获取的两个Car的Seat是相同的。因为Car是单例的,只会在容器启动时创建一次Car,Seat也只会在装配一次,每次从容器中获取都是同一个Car,所以Seat也是相同的。
-
使用@Lookup注解注入prototype组件
-
注释Autowired,在getSeat()方法上添加@Lookup
package com.hl.bean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.stereotype.Component;
@Component
public class Car {
private String name;
// @Autowired
private Seat seat;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Lookup
public Seat getSeat() {
return seat;
}
public void setSeat(Seat seat) {
this.seat = seat;
}
}
-
测试
使用@Lookup,每次获取Seat都从容器中获取,因为Seat是prototity类型,所以每次都创建新的Seat对象。
-
注意:使用@Bean的方式将Car注入容器,@Lookup会失效
-
注释掉Car上的@Component
-
在配置类使用@Bean注解注入Car
-
这样的话结果会变为true
后续分析@Lookup实现源码和@Bean与@Lookup不能一起使用的原因。