@Autowired自动装配
@Autowired不仅可以注解属性,还可以注解普通方法、构造器方法、还有方法参数。
当@Autowired注解属性时,遵循如下逻辑:
①优先按照类型去容器中找对应的组件,找到就赋值;
②如果找到多个相同类型的组件,再将属性名称来作为组件的ID去容器中查找;
③如果想要特定ID的组件来装配,则可以根据@Qualifier注解来明确要求被装配组件的ID名称;或者使用@Primary注解来注解装配的Bean,这样默认就拿这个Bean来装配了;
④@Autowired注解一定要将属性赋值,否则就会报错,可以使用该注解的required属性来设置为可复制,例如:@Autowired(required=false);
当@Autowired注解普通方法时,遵循如下逻辑:
以setPersionDao(PersionDao persionDao)为例来说明:
当@Autowired注解在PersionService.setPersionDao方法上时,Spring容器创建PersionService对象时,就会调用setPersionDao方法来完成赋值,由于setPersionDao方法使用了PersionDao类型的参数persionDao,因此Spring则从IOC容器中获取实例对象(@Autowired注解在方法上与在属性上是一致的);
@Service |
@Repository |
PersionService persionService = applicationContext.getBean(PersionService.class); 错误信息: 七月 23, 2020 9:23:46 下午 org.springframework.context.annotation.AnnotationConfigApplicationContext refresh 警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'persionController': Unsatisfied dependency expressed through field 'persionService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'persionService': Unsatisfied dependency expressed through method 'setPersionDao' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.spring.annotation.PersionDao' available: expected single matching bean but found 2: persionDao,persionDao2
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'persionController': Unsatisfied dependency expressed through field 'persionService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'persionService': Unsatisfied dependency expressed through method 'setPersionDao' parameter 0; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.spring.annotation.PersionDao' available: expected single matching bean but found 2: persionDao,persionDao2 |
当@Autowired注解构造方法时,遵循逻辑与普通方法一致,只不过有个特殊之处:
如果组件只有一个构造器,且还是有参构造器,则这个构造器无需添加@Autowired注解也能从IOC容器中获取参数,即有参构造方法即便没有@Autowired注解也能从IOC容器中获取参数值;
与之类似的效果@Bean注解也有,只不过@Bean注解必须标注方法,这样才能让方法参数从容器中获取,即使用@Bean注解方法后,可以不再使用@Autowired注解;
@Bean |
public PersionService(PersionDao persionDao) { //这里为了验证@Bean注解对@Autowired注解的顶替作用,测试的时候先把这个构造方法注释掉 |
@Service public class PersionService { @Autowired(required = false) @Qualifier("persionDao") private PersionDao persionDao; @Override public String toString() { return "PersionService{" + "persionDao=" + persionDao + '}'; } } @Repository @Primary public class PersionDao { } |
@Resource和@Inject
@Resource:Spring支持JAVA规范自带的JSR250规范,其效果跟@Autowired类似,使用形式如:@Resource(name=”xxxx”),该注解不支持@Primary注解,也不支持@Autowired(required=false);
@Inject:Spring支持JAVA规范自带的JSR330规范,其效果跟@Autowired类似,需要javax.inject包支持,使用形式如:@Inject
Aware接口来自定义组件
通过实现该接口,自定义组件可以直接调用Spring最底层的框架,而Spring框架则根据回调Aware接口里的方法来间接调用自定义组件的方法;
下面是Aware的子接口:
每一个Aware都对应一个AwareProcessor,核心是AwareProcessor来回调Aware,而Aware继续回调用户自己实现的接口方法;
@Profile根据不同环境注册不同组件
①@Profile既可以注解方法,也可以注解类,当注解类的时候,当这个类加载的时候,其内部方法才能生效,否则内部方法无法生效,即便某方法@Profile注解符合被激活的环境;
②没有被@Profile注解的类或方法(前提是当前方法所属类并没有@Profile注解),任何环境下都会被Spring注册;
③@Profile默认环境是default;
那么,如何激活某个环境呢,常用方式有2种:
①使用命令行动态参数方式激活某种环境:
-Dspring.profiles.active=XXX
②使用代码方式激活某种环境:
applicationContext.getEnvironment().setActiveProfiles(XXX);
applicationContext.register(XXX.class);
applicationContext.refresh();
举例:
@Profile("test") |