作者个人研发的在高并发场景下,提供的简单、稳定、可扩展的延迟消息队列框架,具有精准的定时任务和延迟队列处理功能。自开源半年多以来,已成功为十几家中小型企业提供了精准定时调度方案,经受住了生产环境的考验。为使更多童鞋受益,现给出开源框架地址:
https://github.com/sunshinelyz/mykit-delay
PS: 欢迎各位Star源码,也可以pr你牛逼哄哄的代码。
我在 冰河技术 微信公众号中发表的《【Spring注解驱动开发】使用@Autowired@Qualifier@Primary三大注解自动装配组件,你会了吗?》一文中,介绍了如何使用@Autowired、@Qualifier和@Primary注解自动装配Spring组件。那除了这三个注解以外,还有没有其他的注解可以自动装配组件呢?那必须有啊!今天,我们就一起说说@Resource注解和@Inject注解。 关注 冰河技术 微信公众号,回复 “Spring注解”关键字领取源码工程。
@Resource(这个注解属于J2EE的,JSR250),默认安照名称进行装配,名称可以通过name属性进行指定, 如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
@Resource注解的源码如下所示。
package javax.annotation;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface Resource {
String name() default "";
String lookup() default "";
Class<?> type() default java.lang.Object.class;
enum AuthenticationType {
CONTAINER,
APPLICATION
}
AuthenticationType authenticationType() default AuthenticationType.CONTAINER;
boolean shareable() default true;
String mappedName() default "";
String description() default "";
}
@Inject注解(JSR330)默认是根据参数名去寻找bean注入,支持spring的@Primary注解优先注入,@Inject注解可以增加@Named注解指定注入的bean。
@Inject注解的源码如下所示。
package javax.inject;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import java.lang.annotation.Documented;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
@Target({ METHOD, CONSTRUCTOR, FIELD })
@Retention(RUNTIME)
@Documented
public @interface Inject {}
注意:要想使用@Inject注解,需要在项目的pom.xml文件中添加如下依赖。
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
首先,我们将项目中的PersonService类标注在personDao字段上的@Autowired注解和@Qualifier注解注释掉,然后添加@Resource注解,如下所示。
//@Qualifier("personDao")
//@Autowired(required = false)
@Resource
private PersonDao personDao;
接下来,我们运行AutowiredTest类的testAutowired01()方法,输出的结果信息如下所示。
PersonService{personDao=PersonDao{remark='1'}}
可以看到,使用@Resource注解也能够自动装配组件,只不过此时自动装配的是remark为1的personDao。而不是我们在AutowiredConfig类中配置的优先装配的remark为2的personDao。AutowiredConfig类中配置的remark为2的personDao如下所示。
@Primary
@Bean("personDao2")
public PersonDao personDao(){
PersonDao personDao = new PersonDao();
personDao.setRemark("2");
return personDao;
}
我们在使用@Resource注解时,可以通过@Resource注解的name属性显示指定要装配的组件的名称。例如,我们要想装配remark为2的personDao,只需要为@Resource注解添加 name="personDao2"
属性即可。如下所示。
//@Qualifier("personDao")
//@Autowired(required = false)
@Resource(name = "personDao2")
private PersonDao personDao;
接下来,我们再次运行AutowiredTest类的testAutowired01()方法,输出的结果信息如下所示。
PersonService{personDao=PersonDao{remark='2'}}
可以看到,此时输出了remark为2的personDao,说明@Resource注解可以通过name属性显示指定要装配的bean。
在PersonService类中,将@Resource注解注释掉,添加@Inject注解,如下所示。
//@Qualifier("personDao")
//@Autowired(required = false)
//@Resource(name = "personDao2")
@Inject
private PersonDao personDao;
修改完毕后,我们运行AutowiredTest类的testAutowired01()方法,输出的结果信息如下所示。
PersonService{personDao=PersonDao{remark='2'}}
可以看到,使用@Inject注解默认输出的是remark为2的personDao。这是因为@Inject注解和@Autowired注解一样,默认优先装配使用了@Primary注解标注的组件。
不同点
相同点
三种注解都可以实现bean的注入。