@Component 与 @Bean 的区别
@Component(或 @Managed 注解在类上) 与 @Bean (或 @Managed 注解在方法上)设计的目的是一样的,都是注册 Bean 到容器里(接受容器的托管)。
- @Component,是自动注册托管组件
- @Bean,是自动注册托管对象(由 @Bean 方法构建的实例)
提醒:v3.5 后可用 @Managed (托管的意思)同时替代 @Component 与 @Bean
1、注解属性
| 属性 | 描述 | 默认值 | 支持注解 |
|---|---|---|---|
| value | 名字 | @Bean, @Component, @Managed | |
| name | 名字(与 value 互为别名) | @Bean, @Component, @Managed | |
| tag | 标签,用于特征查找 | @Bean, @Component, @Managed | |
| typed | 按类型注册,名字非空时有效(注1) | false | @Bean, @Component, @Managed |
| index | 产生后的对象排序(越小越先) | 0 | @Bean, @Component, @Managed |
| priority (弃用1) | 任件满足后的运行优先级(越大越优) | 0 | @Bean |
| delivered | 要交付能力接口的 (注2) | true | @Bean, @Component, @Managed |
| injected(弃用2) | 要注入的(注3) | false | @Bean |
| autoInject | 自动注入(注3)。注解在方法上时有效 | false | @Bean, @Managed |
| autoProxy | 自动代理(注3)。注解在方法上时有效 | false | @Bean, @Managed |
| initMethod | 初始化方法(v2.8.6 后支持) | @Bean, @Managed | |
| destroyMethod | 注销方法(v2.8.6 后支持) | @Bean, @Managed |
- 注1:托管对象默认是按类型注册的;当有名字时,则以名字注册,若仍需类型注册,需要 typed=true
- 注2:比如过滤器会自动注册到根路由体系
- 注3:
@Bean方法构建托管 bean 的(原则上要求手动装配完成,框架不作自动处理)- 如果内部有“注入注解”要生效,需要
autoInject=true - 如果内部有“拦截注解”要生效,添加
autoProxy=true(v3.6.1 后支持)
- 如果内部有“注入注解”要生效,需要
- 弃用1:v3.5.0 后
priority标为弃用,由@Condition(priority)替代(实际上就是给条件检测用的) - 弃用2:v3.6.1 后
injected标为弃用,由autoInject替代
2、注解主要区别
@Component | @Managed | @Bean | @Managed | |
|---|---|---|
| 自动装配 | 有 | 默认为手动(配置 autoInject=true 后,自动) |
| 自动代理 | 有 | 默认为手动(配置 autoProxy=true 后,自动) |
| 作用范围 | 注解在类上 | 注解在 @Configuration 类的 public 方法上 |
| 单例控制 | 可以声明自己是不是单例 | 只能是单例 |
| 类型注册 | 以实例类型进行注册 (同时会注册,一级父接口类型) | 同时注册返回的 声明类型 和 实例类型 (以及注册,它们的一级父接口类型) |
v3.5 后可用 @Managed 同时替代 @Component(注解在类上) 与 @Bean(注解在方法上)
3、@Component 注解(自动注册托管类)
- 以及 @Configuration,@Controller,@Remoting 都是注解在类上的
- 告诉 Solon,当前是个接受容器托管的类
- 可以声明自己是不是单例
- 通过类路径扫描自动检测并注入到容器中
- 可以 @Inject 东西
- 可以自动装配自己
- 以类型注册时,以实例类型进行注册(同时会注册,一级父接口类型)
其中 @Controller,@Remoting 类的函数会重新包装成 MethodWarp,支持代理效果。
其中 @Component (当有AOP需求时,会自动代理)由 ASM 或 AOT 为其生成代理类,支持代理效果。
4、@Bean 注解(处理需要手动“组装”的托管对象)
- 不能注释在类上
- 只能用于在 @Configuration 类的函数上,中显式声明单个 Bean
- 且,只支持注在 public 函数上
- 意思就是,我要获取这个Bean的时候,框架要按照这种方式去获取这个Bean
- 只能是单例
- 不可以 @Inject 东西(如果有,需要 autoInject=true)
- 需要手动装配
- 以类型注册时,同时注册返回类型和实例类型(以及注册,它们的一级父接口类型)
- 可以返回 void 或 null(比如,做些初始化配置的活)
在应用开发的过程中,如果想要将“第三方库”中的类装配到应用容器中,是没有办法在它的类上添加 @Component 、@Inject 注解的,因此就不能使用自动化装配的方案了。
如果“第三方库”中的类有 @Component 注解,但没有扫描到。可以在启动类上加 @Import 注解进行导入。