1. 程式人生 > 其它 >二(二)、基於註解形式配置bean

二(二)、基於註解形式配置bean

概述:

常用的註解有@Controller @Service @Repository @Component ;一般@Controller放在@Controller類上面即(表現層)標識表現層元件 ;@Service放在Service(業務層)的實現類上面,標識業務層元件 ;@Repository放在Repository(資料處理層)上面,標識持久層元件;@Component一般方式普通實體上面 基本元件,標識一個受到spring容器管理的元件;這幾個沒有明顯區分,其實可以混用但是為了程式碼的可讀性,一般都是按照前面的方式來處理;

基於註解方式配置bean,主要是通過 context:conponent-scan 來掃描 偵測 例項化 classpath下具有特定標識的元件;

一、配置bean:

步驟一、建立如下目錄結構

此外除了5個jar包外,需要新增spring-aop。否則可能報錯;

程式碼如下:

UserController:

 1 package com.lixm.annotation.controller;
 2 
 3 import org.springframework.stereotype.Controller;
 4 
 5 @Controller
 6 public class UserController {
 7 
 8     public void execute() {
 9         System.out.println("usercontroller execute...");
10 } 11 }
View Code

TestObject:

1 package com.lixm.annotation.entity;
2 
3 import org.springframework.stereotype.Component;
4 
5 @Component
6 public class TestObject {
7 
8 }
View Code

UserRepository:

1 package com.lixm.annotation.repository;
2 
3 public interface UserRepository {
4 
5     int
save(); 6 7 }
View Code

UserRepositoryImpl:

 1 package com.lixm.annotation.repository;
 2 
 3 import org.springframework.stereotype.Repository;
 4 
 5 @Repository(value = "userRepository")
 6 public class UserRepositoryImpl implements UserRepository {
 7 
 8     @Override
 9     public int save() {
10         System.out.println("repository save...");
11         return 0;
12     }
13 
14 }
View Code

UserService:

 1 package com.lixm.annotation.service;
 2 
 3 import org.springframework.stereotype.Service;
 4 
 5 import com.lixm.annotation.repository.UserRepository;
 6 
 7 @Service
 8 public class UserService {
 9 
10     private UserRepository userRepository;
11 
12     public int add() {
13         userRepository.save();
14         System.out.println("userService add...");
15         return 0;
16     }
17 
18 }
View Code

步驟二、測試配置的bean:

 1 public class Main {
 2     public static void main(String[] args) {
 3         ApplicationContext context = new ClassPathXmlApplicationContext("bean-annotation.xml");
 4         TestObject testObject = (TestObject) context.getBean("testObject");
 5         UserController userController = (UserController) context.getBean("userController");
 6         UserService userService = (UserService) context.getBean("userService");
 7         UserRepository userRepository = (UserRepository) context.getBean("userRepository");
 8         System.out.println(testObject);
 9         System.out.println(userController);
10         System.out.println(userService);
11         System.out.println(userRepository);
12         ((ConfigurableApplicationContext) context).close();
13     }
14 
15 }
bean-annotation.xml
需要額外引入context名稱空間
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:context="http://www.springframework.org/schema/context"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 6         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
 7 
 8 <!-- 指定spring ioc容器掃描的包 -->
 9 <context:component-scan base-package="com.lixm.annotation"></context:component-scan>
10 
11 </beans>

執行結果為:

com.lixm.annotation.entity.TestObject@166fa74d
com.lixm.annotation.controller.UserController@40f08448
com.lixm.annotation.service.UserService@276438c9
com.lixm.annotation.repository.UserRepositoryImpl@588df31b

說明配置bean成功;

二、context:component-scan屬性:

base-package :

指定需要掃描的基類包,spring容器會掃描這個基類包裡機器子包中所有的類,掃描到具有特定識別符號的類的上面會顯示S;

需要掃描多個包時,用逗號分割;

1 <context:component-scan base-package="com.lixm.annotation"></context:component-scan>

resource-pattern

屬性過濾特定的類
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:context="http://www.springframework.org/schema/context"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 6         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
 7 
 8 <!-- resource-pattern 屬性過濾特定的類 這裡只掃描 com.lixm.annotation.repository的包 -->
 9 <context:component-scan base-package="com.lixm.annotation" resource-pattern="repository/*.class"></context:component-scan>
10 </beans>

這裡只掃描了repository包裡面的class,如果直接執行上面的main方法會報錯;原因是找不到對應的bean;

三、context:component-scan子節點:

exclude-filter 子節點指定排除哪些指定表示式的元件

這裡排除了,@Repository註解標識的類

1 <context:component-scan base-package="com.lixm.annotation" use-default-filters="false">
2      <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
3 </context:component-scan>

context:include-filter子節點

指定包含哪些表示式的元件該子節點需要use-default-filters="false"配合使用
 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:context="http://www.springframework.org/schema/context"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 6         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
 7 
 8 <context:component-scan base-package="com.lixm.annotation" use-default-filters="false">
 9     <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>   
10 </context:component-scan>
11 </beans>

子節點中常用type的說明:

type="annotation"基於註解的配置 type="assignable"指定class或者interface全名
1 <context:component-scan base-package="com.lixm.annotation" use-default-filters="false">
2     <context:include-filter type="assignable" expression="com.lixm.annotation.repository.UserRepository"/>
3 </context:component-scan>

只掃描com.lixm.annotation.repository.UserRepository類;

1 <context:component-scan base-package="com.lixm.annotation" >
2     <context:exclude-filter type="assignable" expression="com.lixm.annotation.repository.UserRepository"/>
3 </context:component-scan>

不掃描com.lixm.annotation.repository.UserRepository類

四、自動裝配:

spring 使用@Autowired來實現實現bean的自動裝配;

自動裝配的實現:

在需要呼叫的bean的類上面加上@Autowired,現在在Controller方法中呼叫Service的方法;實現程式碼如下:

修改UserController

 1 package com.lixm.annotation.controller;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.stereotype.Controller;
 5 
 6 import com.lixm.annotation.service.UserService;
 7 
 8 @Controller
 9 public class UserController {
10 
11  
12     @Autowired(required = true)
13     private UserService userService;
14     public void execute() {
15         userService.add();
16         System.out.println("usercontroller execute...");
17     }
18 }
View Code

修改UserService

 1 package com.lixm.annotation.service;
 2 
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.stereotype.Service;
 5 
 6 import com.lixm.annotation.repository.UserRepository;
 7 
 8 @Service
 9 public class UserService {
10 
11     @Autowired
12     private UserRepository userRepository;
13 
14     public int add() {
15         userRepository.save();
16         System.out.println("userService add...");
17         return 0;
18     }
19 
20 }
View Code

測試自動裝配:

 1     public static void main(String[] args) {
 2         ApplicationContext context = new ClassPathXmlApplicationContext("bean-annotation.xml");
 3         TestObject testObject = (TestObject) context.getBean("testObject");
 4         UserController userController = (UserController) context.getBean("userController");
 5         UserService userService = (UserService) context.getBean("userService");
 6         UserRepository userRepository = (UserRepository) context.getBean("userRepository");
 7         System.out.println(testObject);
 8         System.out.println(userController);
 9         System.out.println(userService);
10         System.out.println(userRepository);
11         userController.execute();
12         ((ConfigurableApplicationContext) context).close();
13         
14     }

執行結果:

com.lixm.annotation.entity.TestObject@701fc37a
com.lixm.annotation.controller.UserController@4148db48
com.lixm.annotation.service.UserService@282003e1
com.lixm.annotation.repository.UserRepositoryImpl@7fad8c79
repository save...
userService add...
usercontroller execute...

執行了bean元件中的方法,說明裝配成功;

關於@Autowired

1.使用位置:普通欄位(即使是非public)一切具有引數的方法都可以應用@Autowired註解;

2.屬性:value 和 require;

value是指定bean的名稱,如果只有一個value屬性,那麼value可以省略;@Autowired("xXXX")等同於@Autowired(“value="xXXX")

required 表示是否一定要裝配該bean;required=true,表示必須有,如果容器中沒有該bean,則報錯;required=false,表示可以沒有有,如果容器中沒有該bean,也不報錯。

required=true的集中情況:

  • 如果查詢bean結果剛好為一個,就將該bean裝配給@Autowired指定的資料
  • 如果查詢bean的結果不止一個,那麼@Autowired會根據名稱來查詢。
  • 如果查詢bean的結果為空,那麼會丟擲異常。解決方法時,使用required=false

3.配合@Qualifier的使用;

當有多個介面實現類的bean時,可以使用@Qualifier("beanName") 指定裝配的bean

其他裝配方式:

spring 還支援@Resource(如果沒有bean名稱,那麼自動採用標註處的變數或方法名作為bean的名稱) 、 @Inject(沒有required屬性)註解推薦使用@Autowired

我從來不相信什麼懶洋洋的自由。我向往的自由是通過勤奮和努力實現的更廣闊的人生。 我要做一個自由又自律的人,靠勢必實現的決心認真地活著。