1. 程式人生 > >Spring通過註解配置bean

Spring通過註解配置bean

簡介及測試

  Spring支援通過註解的方式來配置bean例項。Spring能夠從classpath下自動掃描,偵測和例項化具有特定註解的元件。特定元件包括:
  @Component:基本註解,標識了一個受Spring管理的元件。
  @Repository:標識持久層元件。
  @Service:標識服務車(業務層)元件。
  @Controller:標識表現層元件。
  
  現在模擬一下基本的MVC的呼叫關係,首先分別建立dao層,service層和controller層的元件:

public interface UserDao {
    public void
save(); } @Repository("userDao") public class UserDaoImpl implements UserDao { @Override public void save() { System.out.println("UserDao save..."); } } @Service public class UserService { @Autowired private UserDao userDao; public void save(){ System.out.println("UserService save..."
); userDao.save(); } } @Controller public class UserAction { @Autowired private UserService userService; public void save(){ System.out.println("UserAction save..."); userService.save(); } }

  對於掃描到的元件,Spring有預設的命名策略:使用非限定類名第一個字母小寫的形式命名。也可以在註解中通過value屬性值標識元件的名稱,其中value是預設屬性,可以直接以字串的形式為註解的value屬性賦值,例如在上述程式碼中,我們通過@Repository(“userDao”)的形式將UserDaoImpl例項命名為userDao。
  
  當在元件類上使用了特點的註解之後,還需要在Spring的配置檔案中宣告<context:component-scan>:(在這裡,我的所有要被掃描的元件類都在包com.MySpring.annotation下)
  
beans-annotation.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    <!-- 宣告需要掃描的包 -->
    <!-- 其中base-package屬性指定需要掃描的基類包,spring容器將會掃描這個基類包及其子包中的所有類 -->
    <!-- 當需要掃描多個包時,可以使用逗號分隔 -->
    <context:component-scan base-package="com.MySpring.annotation"></context:component-scan>
</beans>

  另外,<context:component-scan>元素還會自動註冊AutowireAnnotationBeanPostProcessor例項,該例項可以自動裝配具有@Autowired,@Resource,@Inject註解的屬性。(通常都使用@Autowired)

編寫測試類:

public class Test {

    @org.junit.Test
    public void test() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("beans-annotation.xml");
        UserAction userAction = (UserAction) ctx.getBean("userAction");
        userAction.save();
    }

}

  如果報錯如下:
  java.lang.NoClassDefFoundError:org/springframework/aop/TargetSource
  新增對應spring版本的aop jar包即可,例如我新增的是spring-aop-4.0.0.RELEASE.jar。然後即可成功執行:
  image_1b4puqv3opg518ge1m421mvab29.png-18.9kB

關於<context:component-scan>節點

(1). 屬性resource-pattern可以指定掃描基包下特定的類,而非所有類,例如:

<context:component-scan 
base-package="com.MySpring.annotation" 
resource-pattern="autowire/*.java"></context:component-scan>

(2). <context:include-filter>和<context:exclude-filter>子節點分別指明基類包下要包含的目標類和不包含的目標類,其屬性如下:(前兩個比較常用)
image_1b4pvcsid1ofp175psgnuo01ub2m.png-98.9kB

關於@Autowired

  @Autowired註解自動裝配具有相容型別的單個bean屬性。
  預設情況下,所有使用@Autowired註解的屬性都需要設定,當Spring找不到匹配的bean裝配屬性時,會丟擲異常。若某一屬性允許不被設定,可以設定@Autowired註解的required屬性為false。
  預設情況下,當IOC容器裡存在多個型別相容的bean時(例如現在UserDao介面有兩個實現類,UserDaoImpl只是其一),通過型別的自動裝配將無法工作。有兩種解決方式,一種是像上述例子中一樣,通過@Repository(“userDao”)設定UserDaoImpl例項的名稱為userDao,然後在UserService中宣告UserDao元件名為userDao即可。第二種方式是在裝配屬性上使用@Qualifier註解進行設定,例如在UserService中做如下設定:

  @Autowired
    @Qualifier("userDaoImpl")
    private UserDao userDao;

就會載入UserDaoImpl這個實現類的例項。