依賴注入 javax.inject中@Inject、@Named、@Qualifier和@Provider用法
用過Spring框架的我們都知道,每當生成依賴注入的時候,我們都必須生成相應類的set方法,而且要在set方法上面寫上@Autowired,才能實現依賴注入,如下:
Java程式碼- package com.kaishengit.web;
- 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) {
- this.projectService = projectService;
- }
- }
每次都要生成相應的set方法感覺好麻煩,現在如果我們使用javax.inject.jar,只需要在相應類的屬性上面加上@Inject,如下程式碼:
- 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;
- }
@Inject
@Inject支援建構函式、方法和欄位註解,也可能使用於靜態例項成員。可註解成員可以是任意修飾符(private,package-private,protected,public)。注入順序:建構函式、欄位,然後是方法。父類的欄位和方法注入優先於子類的欄位和方法,同一類中的欄位和方法是沒有順序的。
@Inject註解的建構函式可以是無參或多個引數的建構函式。@Inject每個類中最多註解一個建構函式。
在欄位註解:
- 用@Inject註解
- 欄位不能是final的
- 擁有一個合法的名稱
在方法上註解:
- 用@Inject註解
- 不能是抽象方法
- 不能宣告自身引數型別
- 可以有返回結果
- 擁有一個合法的名稱
- 可以有0個或多個引數
@Inject MethodModirers ResultType Identifier(FormalParameterList ) Throws MethodBody
[上述翻譯:inject的doc文件,翻譯不好敬請諒解]
建構函式註解:
- @Inject
- public House(Person owner) {
- System.out.println("---這是房屋建構函式---");
- this.owner = owner;
- }
- @Injectprivate Person owner;
- @Inject
- publicvoid setOwner(Person owner) {
- this.owner = owner;
- }
SpringUtil類:
- publicclass SpringUtil {
- privatestatic ApplicationContext context = null;
- publicstatic ApplicationContext getApplicationContext() {
- if (context == null) {
- context = new ClassPathXmlApplicationContext("spring.xml");
- }
- return context;
- }
- publicstatic ApplicationContext getApplicationContext(String path) {
- returnnew ClassPathXmlApplicationContext(path);
- }
- publicstatic ApplicationContext getAnnotationConfigApplicationContext(String basePackages) {
- returnnew AnnotationConfigApplicationContext(basePackages);
- }
- }
- import javax.inject.Named;
- @Named
- publicclass Person {
- private String name;
- public Person() {
- System.out.println("---這是人的建構函式---");
- }
- public String getName() {
- return name;
- }
- publicvoid setName(String name) {
- this.name = name;
- }
- }
- @Named
- publicclass House {
- @Injectprivate Person owner;
- public House() {
- System.out.println("---這是房屋建構函式---");
- }
- public Person getOwner() {
- return owner;
- }
- publicvoid setOwner(Person owner) {
- this.owner = owner;
- }
- }
- publicclass Test {
- publicstaticvoid 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名稱預設和類名相同。
例如:
- @Namedpublicclass Person
- @Named("p") publicclass 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;
- publicenum User {STUDENT, TEACHER}
- }
- publicinterface IUserDAO {
- int count();
- }
- @Named
- @Genre(user = User.STUDENT)
- publicclass StudentDAO implements IUserDAO{
- @Override
- publicint count() {
- System.out.println("----StudentDAO----");
- return0;
- }
- }
- @Named
- @Genre(user = User.TEACHER)
- publicclass TeacherDAO implements IUserDAO {
- @Override
- publicint count() {
- System.out.println("--TeacherDAO--");
- return0;
- }
- }
- @Named
- publicclass UserDAOProcessor {
- /*對TeacherDAO類的注入,如果對StudentDAO類注入應該是:@Genre(user = User.STUDENT)或@Genre,因為@Genre預設的是STUDENT*/
- @Inject
- private@Genre(user = User.TEACHER) IUserDAO userDAO;
- publicint count() {
- return userDAO.count();
- }
- public IUserDAO getUserDAO() {
- return userDAO;
- }
- public