@Configuration和@Componen:
@Configuration
public class MyTestConfig {
@Bean
public Driver driver(){
Driver driver = new Driver();
driver.setId(1);
driver.setName("driver");
driver.setCar(car());
return driver;
}
@Bean
public Car car(){
Car car = new Car();
car.setId(1);
car.setName("car");
return car;
}
}
测试代码如下
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestApplicationTests {
@Autowired
private Car car;
@Autowired
private Driver driver;
@Test
public void contextLoads() {
boolean result = driver.getCar() == car;
System.out.println(result ? "同一个car" : "不同的car");
}
}
打印结果如下:
同一个car
使用Configuration时在driver和spring容器之中的是同一个对象,而使用Component时是不同的对象。
虽然Component注解也会当做配置类,但是并不会为其生成CGLIB代理Class,所以在生成Driver对象时和生成Car对象时调用car()方法执行了两次new操作,所以是不同的对象。当时Configuration注解时,生成当前对象的子类Class,并对方法拦截,第二次调用car()方法时直接从BeanFactory之中获取对象,所以得到的是同一个对象。
参考:
@Component和@Configuration作为配置类的差别
@Bean
@Bean和 @Configuration的区别
- @Configuration注解中是包含@Component注解的,被@Configuration修饰的类被定义为一个Spring容器(应用上下文)
@Configuration和 @Component的区别
//@Configuration
@Component()
public class Driver {
@Autowired
Car car;
@Bean
public Driver driver() {
Driver driver = new Driver();
driver.setId(1);
driver.setName("driver");
driver.setCar(car);
return driver;
}
@Bean
public Car car() {
Car car = new Car();
car.setId(1);
car.setName("car");
return car;
}
}
会为@Configuration注解返回的@Bean 生成CGLIB代理Class
-
@Bean用在加了@Component的类内,在以后每次调用driver()或者car()获取Driver、Car对象时,不是从Spring单例池中拿,而是每次新new一个类对象出来);
-
@Bean用在加了@Configuration的类内,在以后每次调用driver()或者car()获取Driver、Car对象时,是从Spring单例池中拿,而不是每次新new一个类对象出来。
-
@Bean和@Component两者的目的是一样的,都是注册bean到Spring容器中。
-
@Component注解表明一个类会作为组件类,并告知Spring要为这个类创建bean。
-
@Bean注解告诉Spring这个方法将会返回一个对象,这个对象要注册为Spring应用上下文中的bean。通常方法体中包含了最终产生bean实例的逻辑。@Bean 需要在配置类中使用,即类上需要加上@Configuration注解。
-虽然Component注解也会当做配置类(@Bean用在加了@Component的类内),也可以将return的对象装配到IOC容器中
(@Bean用在加了@Component的类内,在以后每次调用driver()或者car()获取Driver、Car对象时,不是从Spring单例池中拿,而是每次新new一个类对象出来)
但是并不会为其生成CGLIB代理Class,所以在生成Driver对象时和生成Car对象时调用car()方法执行了两次new操作,所以是不同的对象。当时Configuration注解时,生成当前对象的子类Class,并对方法拦截,第二次调用car()方法时直接从BeanFactory之中获取对象,所以得到的是同一个对象。