javax.inject中@Inject、@Named、@Qualifier和@Provider用法

本文深入解析JSR-330标准的@Inject、@Named、@Qualifier和@Singleton注解,探讨其在Spring框架中的应用。通过示例详细说明了这些注解如何用于依赖注入,以及它们与Spring注解如@Autowire的区别和联系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

@Inject

    @Inject支持构造函数、方法和字段注解,也可能使用于静态实例成员。可注解成员可以是任意修饰符(private,package-private,protected,public)。注入顺序:构造函数、字段,然后是方法。父类的字段和方法注入优先于子类的字段和方法,同一类中的字段和方法是没有顺序的。

    @Inject注解的构造函数可以是无参或多个参数的构造函数。@Inject每个类中最多注解一个构造函数。

    在字段注解:

  • 用@Inject注解
  • 字段不能是final的
  • 拥有一个合法的名称

    在方法上注解:

  • 用@Inject注解
  • 不能是抽象方法
  • 不能声明自身参数类型
  • 可以有返回结果
  • 拥有一个合法的名称
  • 可以有0个或多个参数

        @Inject MethodModirers ResultType Identifier(FormalParameterList ) Throws MethodBody

    [上述翻译:inject的doc文档,翻译不好敬请谅解]

    构造函数注解:

 


 
  1. @Inject

  2. public House(Person owner) {

  3. System.out.println("---这是房屋构造函数---");

  4. this.owner = owner;

  5. }

    字段注解:

 

 

@Inject private Person owner;

    方法注解:

 

 


 
  1. @Inject

  2. public void setOwner(Person owner) {

  3. this.owner = owner;

  4. }

    @Inject注解和Spring的@Autoware注解都是根据类型对其进行自动装配。

 

    SpringUtil类:

 


 
  1. public class SpringUtil {

  2. private static ApplicationContext context = null;

  3. public static ApplicationContext getApplicationContext() {

  4. if (context == null) {

  5. context = new ClassPathXmlApplicationContext("spring.xml");

  6. }

  7. return context;

  8. }

  9.  
  10. public static ApplicationContext getApplicationContext(String path) {

  11. return new ClassPathXmlApplicationContext(path);

  12. }

  13.  
  14. public static ApplicationContext getAnnotationConfigApplicationContext(String basePackages) {

  15. return new AnnotationConfigApplicationContext(basePackages);

  16. }

  17. }

Person类:

 

 


 
  1. import javax.inject.Named;

  2.  
  3. @Named

  4. public class Person {

  5. private String name;

  6.  
  7. public Person() {

  8. System.out.println("---这是人的构造函数---");

  9. }

  10.  
  11. public String getName() {

  12. return name;

  13. }

  14.  
  15. public void setName(String name) {

  16. this.name = name;

  17. }

  18. }

House类:

 

 


 
  1. @Named

  2. public class House {

  3. @Inject private Person owner;

  4. public House() {

  5. System.out.println("---这是房屋构造函数---");

  6. }

  7.  
  8. public Person getOwner() {

  9. return owner;

  10. }

  11.  
  12. public void setOwner(Person owner) {

  13. this.owner = owner;

  14. }

  15. }

测试类:

 

 


 
  1. public class Test {

  2. public static void main(String[] args) {

  3. ApplicationContext context = SpringUtil.getApplicationContext(

  4. "test/spring/inject/bean-inject.xml");

  5. House house = (House)context.getBean("house");

  6. Person p = house.getOwner();

  7. p.setName("张三");

  8. System.out.println(house.getOwner().getName());

  9. }

  10. }

输出结果:

 

---这是房屋构造函数---
---这是人的构造函数---
张三

    上述例子在Spring3.1下测试成功,在Spring3.1下,每个构造函数只初始化一次及默认的单例形式,个人感觉如果脱离Spring环境应该每次用都会实例化新的对象,当然根据实现的jar包不同而不同,要不javax.inject下的@Singleton注解就没有什么用途了。

@Named

    @Named和Spring的@Component功能相同。@Named可以有值,如果没有值生成的Bean名称默认和类名相同。

    例如:

@Named public class Person

    该bean的名称就是person。

 

 

@Named("p") public class Person

    如果指定名称,那么就是指定的名称喽。

 

@Qualifier

    任何人都可以定义一个新的修饰语,一个qualifier注解应该满足如下条件:

  • 定义的注解类有@Qualifier,@Retention(RUNTIME)和@Documented。
  • 可以有属性
  • 可以是公共API的一部分
  • 可以用@Target注解限定使用范围

    下面是Qualifier的例子:

Genre注解类:

 


 
  1. @Documented

  2. @Retention(RetentionPolicy.RUNTIME)

  3. @Qualifier

  4. @Target(value = {ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})

  5. public @interface Genre {

  6. User user() default User.STUDENT;

  7. public enum User {STUDENT, TEACHER}

  8. }

用户接口:(对个数进行统计)

 

 


 
  1. public interface IUserDAO {

  2. int count();

  3. }

StudentDAO:

 

 


 
  1. @Named

  2. @Genre(user = User.STUDENT)

  3. public class StudentDAO implements IUserDAO{

  4. @Override

  5. public int count() {

  6. System.out.println("----StudentDAO----");

  7. return 0;

  8. }

  9.  
  10. }

TeacherDAO:

 

  1. @Named

  2. @Genre(user = User.TEACHER)

  3. public class TeacherDAO implements IUserDAO {

  4.  
  5. @Override

  6. public int count() {

  7. System.out.println("--TeacherDAO--");

  8. return 0;

  9. }

  10. }

UserDAOProcessor:

  1. @Named

  2. public class UserDAOProcessor {

  3. /*对TeacherDAO类的注入,如果对StudentDAO类注入应该是:@Genre(user = User.STUDENT)或@Genre,因为@Genre默认的是STUDENT*/

  4. @Inject

  5. private @Genre(user = User.TEACHER) IUserDAO userDAO;

  6.  
  7. public int count() {

  8. return userDAO.count();

  9. }

  10.  
  11. public IUserDAO getUserDAO() {

  12. return userDAO;

  13. }

  14.  
  15. public void setUserDAO(IUserDAO userDAO) {

  16. this.userDAO = userDAO;

  17. }

  18. }

测试类:

  1. public class Test {

  2. public static void main(String[] args) {

  3. ApplicationContext context = SpringUtil.getApplicationContext(

  4. "test/spring/inject/bean-inject.xml");

  5. UserDAOProcessor processor = (UserDAOProcessor)context.getBean("userDAOProcessor");

  6. System.out.println(processor.count());

  7. }

  8. }

输出结果:

--TeacherDAO--
0

    个人对@Qualifier的理解:

  1. 和Spring的@Qualifier大致相同
  2. 单独用@Inject无法满足对接口的注入,无法找到哪个具体类,所以用@Qualifier来确定注入的具体类
  3. 用到@Qualifier的注解中可以有值、无值和用枚举类型

@Singleton

    使用该注解标记该类只创建一次,不能被继承。一般在类上用该注解。

--------------------- 本文来自 binxigogo 的优快云 博客 ,全文地址请点击:https://blog.youkuaiyun.com/binxigogo/article/details/7851924?utm_source=copy

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值