SpringBoot中@Configuration和@Component注解的区别(23)
使用
@Configuration和@Component都是使用于配置类上以代替XML文件中<beans>标签;
@Configuration是@Component的扩展,同样类似的扩展还有@Repository、@Service、@Controller、@RestController等等,而后面四个都是用于传统三层架构中使用的注解;
在被@Configuration注解的类中所有带有@Bean注解的方法都会被CGLib动态代理,而后每次调用这些方法时返回的都是第一次返回的实例;
被@Configuration标记的类不能是final类,不能是本地类、访问修饰符也不能是private。
测试区别
上面说了被@Configuration注解的类中所有带有@Bean注解的方法都会被CGLib动态代理并在第一次调用之后的每次调用时从BeanFactory中返回相同的实例,而@Component注解则不会。下面的例子展示了其区别:
编辑配置类
通过两个实体类测试,School属性包括(String)addr和(Student)student,Student属性有(String)name和(String)age:
//选择配置注解 @Configuration //@Component public class TestConfiguration { //生成shool实例的方法 @Bean public School school() { School school = new School(); school.setAddr(""); school.setStudent(student()); //这里调用student()新建一个对象给school return school; } //生成student实例的方法 @Bean public Student student() { Student student = new Student(); student.setName("xiaoming"); student.setAge(18); return student; } }
编辑控制层用于测试
分别通过注入方式实例化一个school和一个student对象,再判断school中的student对象与刚刚注入的student对象是否是一个对象:
@RestController @RequestMapping("/") public class TestController { @Autowired private School school; //注入school @Autowired private Student student; //注入student @RequestMapping("/test") public String test() { if (school.getStudent() == student) { //判断是否是同一个对象 return "同一个student对象"; } else { return "不同的student对象"; } } }
发送请求查看结果
修改注解为@Component
//选择配置注解 //@Configuration @Component public class TestConfiguration { //生成shool实例的方法 @Bean public School school() { School school = new School(); school.setAddr(""); school.setStudent(student()); //这里调用student()新建一个对象给school return school; } //生成student实例的方法 @Bean public Student student() { Student student = new Student(); student.setName("xiaoming"); student.setAge(18); return student; } }
发送请求再次查看结果
修改
如果想在@Component注解的类中实现每次返回相同的实例可通过@Autowired先将student注入到一个对象,之后在给school赋值的时候使用这个student对象:
//选择配置注解 //@Configuration @Component public class TestConfiguration { @Autowired private Student stu; //生成shool实例的方法 @Bean public School school() { School school = new School(); school.setAddr(""); school.setStudent(stu); //这里使用注入的stu return school; } //生成student实例的方法 @Bean public Student student() { Student student = new Student(); student.setName("xiaoming"); student.setAge(18); return student; } }
继续查看结果