Spring(二十三):Spring自動注入的實現方式


注解注入顧名思義就是通過注解來實現注入,Spring和注入相關的常見注解包含:Autowrired/Resource/Qualifier/Service/Controller/Repository/Component。

  1. Autowired:自動注入,自動從spring的上下文找到合適的bean來注入;
  2. Resource:用來指定bean名稱注入;
  3. Qualifier和Autowired配合使用:指定bean的名稱來注入;
  4. Service、Contoller、Repository分別標記類:Service層類、Contoller層類、數據層存儲層的類,Spring掃描注解配置時,會標記這些類要生成bean;
  5. Component是一種泛指:標記類是組件,Spring掃描注解配置時,會標記這些類要生成bean。

它們之間的區別:

  • Autowired、Resource用來修飾字段、構造函數、或者設置方法實現注入的;
  • Service、Controller、Repository、Component是修飾類,標記這些類要生成bean。

接下來我們新建一個maven項目來看看spring注解自動注入的使用:

使用AnnotationConfigApplicationContext(basePackages)初始化ApplicationContext方式

1)新家maven項目(Learn-Spring-01)
在Pom.xml引入spring依賴:

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <!--Spring版本號 -->
        <org.springframework.version>5.2.0.RELEASE</org.springframework.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${org.springframework.version}</version>
        </dependency>
        。。。
    </dependencies>

2)新建Article和ArticleDao類,並給ArticleDao類上加上 @Repository 注解
Article實體類:

package com.dx.test.model;

public class Article {
    private Long id;
    private String title;
    private String author;
    private String content;

    。。。。

    @Override
    public String toString() {
        return "Article [id=" + id + ", title=" + title + ", author=" + author + ", content=" + content + "]";
    }
}

ArticleDao類(數據操作類):

package com.dx.test.dao;

import org.springframework.stereotype.Repository;

import com.dx.test.model.Article;

@Repository
public class ArticleDao {
    /**
     * 根據文章id,查詢文章詳情實體
     * 
     * @param id 文章id
     * @return 返回查找到的文章詳情
     */
    public Article getById(Long id) {
        Article article = new Article();
        article.setId(1L);
        article.setTitle("Test Article");
        article.setAuthor("Admin");
        article.setContent("The Article's Content");

        return article;
    }
}

3)新建Service類ArticleService,並在ArticleService類上加上 @Service 注解,在這個類中定義 ArtileDao的字段,並通過 @Autowired 來修飾該字段,這樣上面定義的 ArticleDao 類的實例就會自動被注入到 ArticleService 的實例中:

package com.dx.test.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.dx.test.dao.ArticleDao;
import com.dx.test.model.Article;

@Service
public class ArticleService {
    @Autowired
    private ArticleDao articleDao;

    /**
     * 根據文章id,查詢文章實體詳情
     * 
     * @param id 文章id
     * @return 返回查找文章詳情
     */
    public Article getById(Long id) {
        return articleDao.getById(id);
    }
}

注意:@Autowired 注解有一個可以為空的required屬性,可以用來指定字段是否是必須的,如果必須的,則在找不到合適的實例時會拋出異常。
4)在com.dx.test.App的main方法中使用Spring代碼方式自動注入ArticleDao、ArticleService。

package com.dx.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.dx.test.model.Article;
import com.dx.test.service.ArticleService;

/**
 * Hello SpringFramework!
 */
public class App {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext("com.dx.test.dao",
                "com.dx.test.service");
        ArticleService articleService = applicationContext.getBean(ArticleService.class);
        Article article = articleService.getById(1L);
        System.out.println(article);
    }
}

上面的main方法中首先我們初始化了applicationContext實例,它是AnnonationConfigApplicationContext,它的構造函數接受 basePackages 的名稱,來限定掃描的package范圍。然后就可以通過applicationContext#getBean()方法獲得 ArticleService 的實例。

此時運行控制打印信息如下:

Article [id=1, title=Test Article, author=Admin, content=The Article's Content]

使用代碼注入+spring xml配置文件方式

實際上在SSM(Spring+SpringMVC+Mybatis)項目中,更多的習慣於使用注解+spring xml配置方式,實現自動注入。

在maven測試工程中的src/main/resources下,新建applicationContext.xml的spring配置文件,其內容如下:

 

實際上在SSM(Spring+SpringMVC+Mybatis)項目中,更多的習慣於使用注解+spring xml配置方式,實現自動注入。
在maven測試工程中的src/main/resources下,新建applicationContext.xml的spring配置文件,其內容如下:
<?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-4.0.xsd
 http://www.springframework.org/schema/context
 http://www.springframework.org/schema/context/spring-context-4.0.xsd ">

    <!-- bean annotation driven -->
    <context:annotation-config />
    <context:component-scan base-package="com.dx.test.dao,com.dx.test.service" >
    </context:component-scan>

    <bean id="testArticleDao" class="com.dx.test.dao.ArticleDao" />
    
 </beans>

在上面配置中,我們通過 <context:annotation-config /> 和 <context:component-scan ... /> 兩個配置節點,來指定要掃描注解注入,然后又定義了一個 id 為 testArticleDao 的bean。
因為這里我們使用注解+spring xml配置的方式實現自動注入,那么在初始化ApplicationContext類的方式就需要修改下,加載配置文件方式在Spring中包含兩個接口:ClassPathXmlApplicationContext 或 FileSystemXmlApplicationContext,這里我們采用 ClassPathXmlApplicationContext 方式來實現初始化ApplicationContext。實現代碼如下:

package com.dx.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.dx.test.model.Article;
import com.dx.test.service.ArticleService;

/**
 * Hello SpringFramework!
 */
public class App {
    public static void main(String[] args) {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        ArticleService articleService = applicationContext.getBean(ArticleService.class);
        Article article = articleService.getById(1L);
        System.out.println(article);
    }
}

運行程序輸出為:

Article [id=1, title=Test Article, author=Admin, content=The Article's Content]

上面applicationContext.xml中我們定義了一個id為 testArticleDao 的bean,那么在 ArticleService 中注入 ArticleDao的bean時,我們可以通過@Resource(name="testArticleDao")的方式注入:

@Resources(name="testArticleDao")
private ArticleDao articleDao;

當然我們也可以使用 @Qualifier("testArticleDao")+@Autowired 的方式替代 @Resources(mane="testArticleDao")的方式。

@Autowired
@Qualifier("testArticleDao")
private ArticleDao articleDao;

注意:

1)Resource本身不是spring提供的,從它的命名空間可以得知:javax.annotation.Resource;

2)@Resource注解實現的效果等同於 @Autowired+@Qualifier的效果。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM