开发中经常用到的注解有以下几个:
①:@Autowired:是(JSR-330)javax.inject.inject的替代形式,实现Spring依赖注入的一种形式,可以装配对象,设置对象依赖,注入Setter方法,找到多个Bean对象时需要用@Qualifier限定使用哪个Bean。
使用示例:
方式1:
@Autowired(required=true)
IDemoService autowiredService;
备注:required=true代表依赖是必须的,false代表依赖不是必然的。
方式2:
@Autowired
@Qualifier("autowiredDemoService")
IDemoService autowiredService;
备注:当存在多个Bean实例时@Qualifier起到指定候选Bean的作用。
如何注入对象的同时再设置被注入对象的属性值。
可以有三种形式,作用都一样,只不过其代理实现机制不一样而已。
@Autowired
void setResponseByAutowired(AutowiredDemoService autowiredService) {
autowiredService.setOk("autowired response");
}
@Resource
void setResponseWithResouceAnnotation(AutowiredDemoService autowiredService) {
autowiredService.setOk("resource response");
}
@Inject
void setResponseByAutowiredAgain(AutowiredDemoService autowiredService) {
autowiredService.setOk("autowiredAgain response");
}
源码分析:
@Autowired由AutowiredAnnotationBeanPostProcessor实现,它里面有两个重要的内部类,AutowiredFieldElement和AutowiredMethodElement,这两个类都继承自InjectionMetadata.InjectedElement,并重写了inject(注入方法),这两个类的作用一个是注解在属性字段的注入,另一个是注解在方法上的注入。
简单说一下这个类里面的其他方法是做什么用的。
Method:findAutowiringMetadata->找到所有装配的元数据
Method:registerDependentBeans ->将指定的Bean注册它的依赖Bean(比方说;xxService注册到xxController中去)
②:@Resource:资源标记注解,由J2EE提供的注解(javax.annotation.Resource)。当组件初始化时,容器将向应用程序组件注入请求资源的实例。重点就是:标记应用程序所需的资源,资源在Spring中可能以Component,Service,以@Bean注入形式等。@Resource默认是ByName方式注入资源。
特性:支持byName,byType多种形式。
@Resource注解核心实现实在类CommonAnnotationBeanPostProcessor中实现的,我们就简单说一下这个类针对Resource做了什么用。
通过查看源码得出,里面有一个内部类:ResourceElement,还有一个重要方法:buildResourceMetadata->构建ResourceMetaData(Resource元素据)
//构造ResourceElement函数
public ResourceElement(Member member, AnnotatedElement ae, @Nullable PropertyDescriptor pd) {
Resource resource = ae.getAnnotation(Resource.class);
String resourceName = resource.name();
Class<?> resourceType = resource.type();
this.isDefaultName = !StringUtils.hasLength(resourceName);
if (this.isDefaultName) {
resourceName = this.member.getName();
if (this.member instanceof Method && resourceName.startsWith("set") && resourceName.length() > 3) {
resourceName = Introspector.decapitalize(resourceName.substring(3));
}
}
else if (embeddedValueResolver != null) {
resourceName = embeddedValueResolver.resolveStringValue(resourceName);
}
if (Object.class != resourceType) {
checkResourceType(resourceType);
}
else {
// No resource type specified... check field/method.
resourceType = getResourceType();
}
this.name = (resourceName != null ? resourceName : "");
this.lookupType = resourceType;
String lookupValue = resource.lookup();
this.mappedName = (StringUtils.hasLength(lookupValue) ? lookupValue : resource.mappedName());
Lazy lazy = ae.getAnnotation(Lazy.class);
this.lazyLookup = (lazy != null && lazy.value());
}
@Resource和@Autowired的相同点:
①:都是注解形式,都可以用来依赖注入,都可以以配置在属性上的形式依赖一个Bean,也可以以Setter形式注入一个Bean.两者的注入形式都可以被javax.inject.Inject注解取代。
②:两者都依赖于Spring上下文,都需要先获取BeanFacotry之后,再由BeanFactory去解析Bean,装配Bean等动作。
③:他们俩都可以配置延时加载(以@Lazy配置使用,这样做时用到时才会装配,才会报错,与懒加载是一层意思。
@Resource和@Autowired的不同点:
①:来源不同,@Resource是J2EE里面的注解,不依赖于Spring.
@Autowired是来自于Spring-Beans里面的注解,必须在Spring容器中才能使用,并依赖于Spring上下文。
②:使用的范围@Resource比@Autowired更广泛,@Resource除了ByType之外还可以ByName。@Resource指定name时相当于@Autowired与@Qualifer组合使用.
③:@Resource可以设置一定的容错性,可以配置lookUp,可以指定Type来装配。
网友评论