spring中Configuration和Component的区别
Configuration和Component都是Spring中用来注册Bean的注解,两者的目的是一样的,但是,产生的效果略有不同,点开Configuration的注解源码,会发现@Configuration注解还是基于@Component注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
@AliasFor(
annotation = Component.class
)
String value() default "";
boolean proxyBeanMethods() default true;
}
(1) @configuration的注解本质还是@component,因此对于@configuration注解标记的bean依然能够通过<context:component-scan/>或者@componentScan进行代理实例化
(2) @configuration注解的bean里面带有@bean注解的方法都会被动态代理,因此调用该方法返回的都是同一个实例,被configuration注解的bean实际是变成一个增强类
(3) @configuration是通过cglib来代理@bean方法的使用, @component注解并没有。
使用代码比较两者差异:
@Configuration
public class User {
private Long id;
private String name;
public Long getId() {
return new Random().nextLong();
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
@Component
public class CompUser {
@Bean("user2")
public User getUser() {
return new User();
}
}
@Configuration
public class ConfigUser {
@Bean("user1")
public User getUser() {
return new User();
}
}
@Configuration
@EnableScheduling
public class CompareConfigAndComp {
@Autowired
CompUser compUser;
@Autowired
ConfigUser configUser;
@Scheduled(cron = "0/3 * * * * ?")
public void task() {
System.out.println(configUser.getUser()+ ">>>>>>>>>>>>>>>>" + compUser.getUser());
System.out.println(configUser.getUser().hashCode() + ">>>>>>>>>>>>>>>>" + compUser.getUser().hashCode());
}
}
@SpringBootApplication
public class WebApplication {
public static void main(String[] args) {
SpringApplication.run(WebApplication.class);
}
}
为了方面上面代码基于springboot框架,引入了spring-boot-starter启动springboot,得到执行结果
2020-01-17 14:31:33.056 INFO 10684 --- [ main] o.s.s.c.ThreadPoolTaskScheduler : Initializing ExecutorService 'taskScheduler'
2020-01-17 14:31:33.086 INFO 10684 --- [ main] com.fan.springbootdemo.WebApplication : Started WebApplication in 0.948 seconds (JVM running for 1.34)
1097324923>>>>>>>>>>>>>>>>611542068
1097324923>>>>>>>>>>>>>>>>716476106
1097324923>>>>>>>>>>>>>>>>780865348
1097324923>>>>>>>>>>>>>>>>1804174577
1097324923>>>>>>>>>>>>>>>>1424236400
会发现@Configuration注解的类中,User对象的hashcode一直不变,说明User对象只被初始化了一次,这说明在注册ConfigUser对象时,就初始化了User对象,而@Component注解的类,每次获取User对象的hashcode都不同,说明@Component不会在注册CompUser对象时就初始化User,而是调用getUser方法才创建.综上,所以当使用场景中,需要一次性初始化所有Bean就使用@configuration,不需要就使用@component