@Inject 使用

这个是 Java EE 6 规范 JSR 330 – Dependency Injection for Java 中的东西,也就是 Java EE 的依赖注入。
根据 API document 上的说明,被 @Inject 标注的构造、成员字段和方法是可注入的。

用过Spring框架的我们都知道,每当生成依赖注入的时候,我们都必须生成相应类的set方法,而且要在set方法上面写上@Autowired,才能实现依赖注入,如下:

import com.kaishengit.service.ProjectService;  
import org.springframework.beans.factory.annotation.Autowired;                 
import org.springframework.stereotype.Controller;                              
@Controller                                                                    
public class FolderController {                                                
    private ProjectService projectService;                                     
     //set                                                                     
     @Autowired                                                                
     public void setProjectService(ProjectService projectService) {  @Component
         this.projectService = projectService;                                 
     }                                                                         
 }                                                                             

这样每次都要生成相应的set方法非常麻烦,现在如果我们使用javax.inject.jar,只需要在相应类的属性上面加上@Inject,如下代码:
Java代码

package com.kaishengit.web;                       
import com.kaishengit.service.ProjectService;     
import org.springframework.stereotype.Controller; 
import javax.inject.Inject;                       
@Controller                                       
public class FolderController {                   
     @Inject                                      
     private ProjectService projectService;       
}                                                

javax.inject.jar下载地址:点我

@Inject

@Inject支持构造函数、方法和字段注解,也可能使用于静态实例成员。可注解成员可以是任意修饰符(private,package-private,protected,public)。

注入顺序:构造函数、字段,然后是方法。父类的字段和方法注入优先于子类的字段和方法,同一类中的字段和方法是没有顺序的。

@Inject注解的构造函数可以是无参或多个参数的构造函数。@Inject每个类中最多注解一个构造函数。
1. 在字段注解
用@Inject注解
● 字段不能是final的
● 拥有一个合法的名称
2. 在方法上注解
● 用@Inject注解
● 不能是抽象方法
● 不能声明自身参数类型
● 可以有返回结果
● 拥有一个合法的名称
● 可以有0个或多个参数

构造函数注解:

@Inject  
 public House(Person owner) {  
    System.out.println("---这是房屋构造函数---");  
    this.owner = owner;  
 }  

字段注解:

@Inject private Person owner;  

方法注解:

@Inject  
public void setOwner(Person owner) {  
  this.owner = owner;  
}  

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

测试
SpringUtil类:

public class SpringUtil {                                                                          
    private static ApplicationContext context = null;                                              
    public static ApplicationContext getApplicationContext() {                                     
        if (context == null) {                                                                     
            context = new ClassPathXmlApplicationContext("spring.xml");                            
        }                                                                                          
        return context;                                                                            
    }                                                                                              
   public static ApplicationContext getApplicationContext(String path) {                         
         return new ClassPathXmlApplicationContext(path);                                          
     }                                                                                             
   public static ApplicationContext getAnnotationConfigApplicationContext(String basePackages) { 
         return new AnnotationConfigApplicationContext(basePackages);                              
     }                                                                                             
 }                                                                                                 

Person类:

 import javax.inject.Named;                           
@Named                                               
public class Person {                                
    private String name;                             
public Person() {                                
        System.out.println("---这是人的构造函数---");        
    }                                                
  public String getName() {                       
         return name;                                
     }                                               
 public void setName(String name) {              
         this.name = name;                           
     }                                               
 }                                                   

House类:

 @Named                                              
public class House {                                
    @Inject private Person owner;                   
    public House() {                                
        System.out.println("---这是房屋构造函数---");       
    }                                               

    public Person getOwner() {                      
        return owner;                               
     }                                              

     public void setOwner(Person owner) {           
         this.owner = owner;                        
     }                                              
 }                                                  

测试类:

  public class Test {                                                   
    public static void main(String[] args) {                          
        ApplicationContext context = SpringUtil.getApplicationContext(
                "test/spring/inject/bean-inject.xml");                
        House house = (House)context.getBean("house");                
        Person p = house.getOwner();                                  
        p.setName("张三");                                              
        System.out.println(house.getOwner().getName());               
    }                                                                 
 }                                                                    

输出结果:

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

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

@Named

@Named和Spring的@Component功能相同。@Named可以有值,如果没有值生成的Bean名称默认和类名相同。
例如:
1. @Named public class Person
该bean的名称就是person。
2. @Named(“p”) public class Person
如果指定名称,那么就是指定的名称喽。

@Qualifier

任何人都可以定义一个新的修饰语,一个qualifier注解应该满足如下条件:
● 定义的注解类有@Qualifier,@Retention(RUNTIME)和@Documented。
● 可以有属性
● 可以是公共API的一部分
● 可以用@Target注解限定使用范围

下面是Qualifier的例子:
Genre注解类:

@Documented                                                                  
@Retention(RetentionPolicy.RUNTIME)                                          
@Qualifier                                                                   
@Target(value = {ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE})
public @interface Genre {                                                    
    User user() default User.STUDENT;                                        
    public enum User {STUDENT, TEACHER}                                      
}                                                                            

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

public interface IUserDAO {  
  int count();  
}  

StudentDAO:

@Named                                            
@Genre(user = User.STUDENT)                       
public class StudentDAO implements IUserDAO{      
    @Override                                     
    public int count() {                          
        System.out.println("----StudentDAO----"); 
        return 0;                                 
    }                                             
 }                                                

TeacherDAO:

@Named                                       
@Genre(user = User.TEACHER)                  
public class TeacherDAO implements IUserDAO {
    @Override                                
    public int count() {                     
        System.out.println("--TeacherDAO--");
        return 0;                            
    }                                        
 }                                           

UserDAOProcessor:

@Named                                                                                                                 
public class UserDAOProcessor {                                                                                        
    /*对TeacherDAO类的注入,如果对StudentDAO类注入应该是:@Genre(user = User.STUDENT)或@Genre,因为@Genre默认的是STUDENT*/                     
    @Inject                                                                                                            
    private @Genre(user = User.TEACHER) IUserDAO userDAO;                                                              

    public int count() {                                                                                               
        return userDAO.count();                                                                                        
    }                                                                                                                  

     public IUserDAO getUserDAO() {                                                                                    
         return userDAO;                                                                                               
     }                                                                                                                 

     public void setUserDAO(IUserDAO userDAO) {                                                                        
         this.userDAO = userDAO;                                                                                       
     }                                                                                                                 
 }                                                                                                                     

测试类:

public class Test {                                                                         
     public static void main(String[] args) {                                               
         ApplicationContext context = SpringUtil.getApplicationContext(  T*/                
                 "test/spring/inject/bean-inject.xml");                                     
         UserDAOProcessor processor = (UserDAOProcessor)context.getBean("userDAOProcessor");
         System.out.println(processor.count());                                             
     }                                                                                      
 }                                                                                          

输出结果:

–TeacherDAO–
0

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

@Singleton

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

  • 2
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值