首頁 > 軟體

Spring IOC容器的Bean管理基於註解屬性注入方式

2022-05-30 18:01:31

基於註解方式進行屬性注入

涉及到 4 個註解

  • @Autowired:根據屬性型別,進行自動裝配
  • @Qualifier:根據屬性名稱進行注入,跟 @Autowired 一起使用
  • @Resource:既可以根據型別注入,也可以根據名稱注入
  • @Value:注入普通型別屬性

一、@Autowired

現在有這樣的一個結構,我要在 service 裡注入 dao 物件。

1. 新增物件註解

給 service 和 dao 新增註解,用來建立物件。

為了區分明顯,service 層用 @Service,dao 層用 @Repository。

// content of UserService
@Service
public class UserService {
    public void add() {
        System.out.println("service add() ... ...");
    }
}
@Repository
public class UserDaoImpl implements UserDao{
    @Override
    public void add() {
        System.out.println("UserDao add()... ...");
    }
}

2. 在service中注入dao物件

@Service
public class UserService {
    // 定義 dao 屬性
    @Autowired
    private UserDao userDao;
    public void add() {
        System.out.println("service add() ... ...");
        userDao.add();
    }
}

先定義 dao 屬性,然後在上面新增註解 @Autowired 即可,而且不需要我們手動新增 set 方法了。

為了方便看到注入成功效果,裡面還呼叫了 userDao.add() 方法。

3. 建立測試函數測試效果

public class TestService {
    @Test
    public void testService() {
        ApplicationContext context
                = new ClassPathXmlApplicationContext("bean1.xml");
        UserService userService = context.getBean("userService", UserService.class);
        System.out.println(userService);
        userService.add();
    }
}

這裡呼叫了 userService.add() 方法,而 userService.add() 內部又呼叫了 userDao.add(),所以應該可以看到 2 個輸出:

com.pingguo.spring5.service.UserService@23f7d05d
service add() ... ...
UserDao add()... ...
Process finished with exit code 0

二、@Qualifier

根據屬性名稱進行注入,跟 @Autowired 一起使用。

為什麼要一起使用?

比如現在,我新增一個 dao 的實現類 UserDaoImpl2

@Repository
public class UserDaoImpl2 implements UserDao {
    @Override
    public void add() {
        System.out.println("UserDao UserDaoImpl2 add()... ...");
    }
}

所以現在 UserDaoImpl 和 UserDaoImpl2 這2個類都是同一種型別,那麼 @Autowired 注入的時候到底是用哪個類呢?於是報錯了。

所以,要加上 @Qualifier 來指定其中一個的具體名稱。比如,我這裡使用 UserDaoImpl2 。

再次執行測試函數:

com.pingguo.spring5.service.UserService@75f32542
service add() ... ...
UserDao UserDaoImpl2 add()... ...
Process finished with exit code 0

可以看到 UserDaoImpl2 裡的內容被輸出,注入正確。

三、@Resource

既可以根據型別注入,也可以根據名稱注入。

1. 替代 @Autowired

可以直接替代 @Autowired 使用。

現在我把 UserDaoImpl2 這個實現類註釋掉,只留下一個實現類。

service 裡使用 @Resource 註解:

@Service
public class UserService {
    // 定義 dao 屬性
    @Resource
    private UserDao userDao;
    public void add() {
        System.out.println("service add() ... ...");
        userDao.add();
    }
}

執行測試:

com.pingguo.spring5.service.UserService@23f7d05d
service add() ... ...
UserDao add()... ...
Process finished with exit code 0

結果正確。

2. 替換 @Qualifier

替換 @Qualifier 使用的話,裡面的值用 name 傳遞,比如 @Resource(name = "userDaoImpl2")

現在去掉 UserDaoImpl2 的註釋,讓 dao 有 2 個實現類。

service 中 使用 @Resource 註解:

@Service
public class UserService {
    // 定義 dao 屬性
    @Resource(name = "userDaoImpl2")
    private UserDao userDao;
    public void add() {
        System.out.println("service add() ... ...");
        userDao.add();
    }
}

執行測試:

com.pingguo.spring5.service.UserService@197d671
service add() ... ...
UserDao UserDaoImpl2 add()... ...
Process finished with exit code 0

結果正確。

這裡要提一下的是,Resource 是來自拓展包 javax。另外 2個 則是來自官方框架包,優先使用。

四、@Value

上面使用的都是注入物件型別的屬性,使用 @Value 可以注入普通型別,比如 String。

在 service 裡增加一個 String 型別的屬性 userName,並且在下面的方法裡做個列印輸出。

@Service
public class UserService {
    // 定義 dao 屬性
    @Autowired
    @Qualifier(value = "userDaoImpl2")
    private UserDao userDao;
    @Value(value = "spring 從0開始")
    private String userName;
    public void add() {
        System.out.println("service add() ... ...");
        System.out.println(userName);
        userDao.add();
    }
}

執行測試:

com.pingguo.spring5.service.UserService@184cf7cf
service add() ... ...
spring 從0開始
UserDao UserDaoImpl2 add()... ...
Process finished with exit code 0

注入成功。

以上就是Spring IOC容器的Bean管理基於註解屬性注入方式的詳細內容,更多關於Spring IOC Bean註解屬性注入的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com