程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 【譯】Spring 4 自動裝配、自動檢測、組件掃描示例(基於注解),spring示例

【譯】Spring 4 自動裝配、自動檢測、組件掃描示例(基於注解),spring示例

編輯:JAVA綜合教程

【譯】Spring 4 自動裝配、自動檢測、組件掃描示例(基於注解),spring示例


前言

譯文鏈接:http://websystique.com/spring/spring-auto-detection-autowire-component-scanning-example-with-annotations/

在本篇文章我們會看到Spring是如何通過component-scanning配置,在沒有使用@Bean和@Configuration聲明bean,也沒有使用XML配置聲明bean的情況下,自動檢測到程序中配置的bean,並且自動裝配這些bean。

對於component-scanning的配置,本文將使用@ComponentScan注解,當然,我們也會提供一份對應的XML配置來作為比較。

我們將創建一個典型的企業級應用示例,涉及不同的層(Service、DAO)。

涉及的技術及開發工具

  • Spring 4.0.6.RELEASE
  • Joda-time 2.3
  • Maven 3
  • JDK 1.6
  • Eclipse JUNO Service Release 2

工程結構目錄

如下是本工程的目錄結構

接下來開始往上面添加具體內容。

步驟一:往pom.xml添加Spring依賴

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
 
  <groupId>com.websystique.spring</groupId>
  <artifactId>Spring4AutoScanning</artifactId>
  <version>1.0.0</version>
  <packaging>jar</packaging>
 
  <name>Spring4AutoScanning</name>
    <properties>
        <springframework.version>4.0.6.RELEASE</springframework.version>
        <joda-time.version>2.3</joda-time.version>
    </properties>
 
    <dependencies>
        <!--  Spring -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${springframework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${springframework.version}</version>
        </dependency>
 
        <!-- Joda-Time -->       
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
            <version>${joda-time.version}</version>
        </dependency>
 
    </dependencies>
    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <version>3.2</version>
                    <configuration>
                        <source>1.6</source>
                        <target>1.6</target>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>
 
</project>

這個示例,我們使用了Spring-core和Spring-context依賴,另外,還使用了JodaTime的LocalDate類來做一些日期計算,所以引入了joda-time依賴。

步驟二:創建Spring配置類

Spring配置類是用@Configuration注解標注的,這些類包含了用@Bean注解標注的方法,這些方法生成bean會交給Spring容器來管理。

package com.websystique.spring.configuration;
 
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
 
@Configuration
@ComponentScan(basePackages = "com.websystique.spring")
public class AppConfig {
 
}

你可能注意到上面的類是空的,沒有使用@Bean標注的方法,那麼bean從哪裡產生呢?

事實上,我們使用了@ComponentScan注解,來幫助我們自動檢測bean

@ComponentScan(basePackages = "com.websystique.spring")

@ComponentScan注解的basePackages屬性是一個包名,配置好後,將會在該包下查找所有使用特定注解標注的類,作為bean。

如下是一些常見的注解,被這些注解標注的類是一個bean,將會被自動檢測

@Repository - 作為持久層的DAO組件.
@Service - 作為業務層的Service組件.
@Controller - 作為展現層的Controller組件.
@Configuration - Configuration組件.
@Component - 通用注解, 可以作為以上注解的替代.

注意上面的注解內部都是用@Component標注的,所以實際上你可以在任何地方使用@Component, 但是為了表達更加清晰的設計意圖,強烈建議根據不同情況使用不同的注解。

注意:在我們這裡例子,你甚至可以直接刪除配置類因為它並沒有包含任何@Bean注解標注的方法,在後面的main方法裡我們將會看到在這種情況下是如何掃描這些Bean。

另外,看下使用XML配置的情況,結果如下(命名為app-config.xml)

<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">
  
    <context:component-scan base-package="com.websystique.spring" />
  
</beans>

步驟三:創建DAO層的類

package com.websystique.spring.dao;
 
import com.websystique.spring.model.Employee;
 
public interface EmployeeDao {
 
    void saveInDatabase(Employee employee);
}
package com.websystique.spring.dao;
 
import org.springframework.stereotype.Repository;
 
import com.websystique.spring.model.Employee;
 
@Repository("employeeDao")
public class EmployeeDaoImpl implements EmployeeDao{
 
    public void saveInDatabase(Employee employee) {
 
        /*
         * Logic to save in DB goes here
         */
        System.out.println("Employee "+employee.getName()+" is registered for assessment on "+ employee.getAssessmentDate());
         
    }
 
}

@Repository注解標注該類作為一個持久層自動檢測的bean,參數employeeDao為bean提供了一個名字,我們將會在主服務Bean裡注入該bean。

步驟四:創建Service層類

package com.websystique.spring.service;
 
import org.joda.time.LocalDate;
 
public interface DateService {
 
    LocalDate getNextAssessmentDate();
}
package com.websystique.spring.service;
 
import org.joda.time.LocalDate;
import org.springframework.stereotype.Service;
 
@Service("dateService")
public class DateServiceImpl implements DateService{
 
    public LocalDate getNextAssessmentDate() {
        return new LocalDate(2015,10,10);
    }
 
}

@Service注解標注這個類為業務層自動檢測的bean,後續我們會將其注入到主服務bean中。

package com.websystique.spring.service;
 
import com.websystique.spring.model.Employee;
 
public interface EmployeeService {
 
    void registerEmployee(Employee employee);
}
package com.websystique.spring.service;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import com.websystique.spring.dao.EmployeeDao;
import com.websystique.spring.model.Employee;
 
@Service("employeeService")
public class EmployeeServiceImpl implements EmployeeService{
 
    @Autowired
    private DateService dateService;
     
    @Autowired
    private EmployeeDao employeeDao;
     
 
    public void registerEmployee(Employee employee) {
        employee.setAssessmentDate(dateService.getNextAssessmentDate());
        employeeDao.saveInDatabase(employee);
    }
     
}

EmployeeService是我們的主服務類,可以看到,我們往這個類注入了DateService和EmployeeDao。被@Autowired注解標注的dateService屬性,會被Spring的依賴注入自動裝配合適的Bean,由於我們已經使用@Service聲明了一個DateService Bean,所以該Bean將會被注入到這裡。類似的,被@Repository標注的EmployeeDao也會被注入到employeeDao屬性中。

如下是我們的實體類Employee

package com.websystique.spring.model;
 
import org.joda.time.LocalDate;
 
public class Employee {
 
    private int id;
 
    private String name;
 
    private LocalDate assessmentDate;
 
    public int getId() {
        return id;
    }
 
    public void setId(int id) {
        this.id = id;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public LocalDate getAssessmentDate() {
        return assessmentDate;
    }
 
    public void setAssessmentDate(LocalDate assessmentDate) {
        this.assessmentDate = assessmentDate;
    }
 
    @Override
    public String toString() {
        return "Employee [id=" + id + ", name=" + name + ", assessmentDate="
                + assessmentDate + "]";
    }
 
}

步驟五:創建main方法運行該程序

package com.websystique.spring;
 
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.AbstractApplicationContext;
 
import com.websystique.spring.configuration.AppConfig;
import com.websystique.spring.model.Employee;
import com.websystique.spring.service.EmployeeService;
 
public class AppMain {
 
    public static void main(String args[]){
        AbstractApplicationContext  context = new AnnotationConfigApplicationContext(AppConfig.class);
         
        EmployeeService service = (EmployeeService) context.getBean("employeeService");
 
        /*
         * Register employee using service
         */
        Employee employee = new Employee();
        employee.setName("Danny Theys");
        service.registerEmployee(employee);
         
        context.close();
    }
}

運行上面的程序,會看到如下結果:

Employee Danny Theys is registered for assessment on 2016-12-22

另外,假如你想不使用配置類AppConfig,那麼還可以這樣做:

package com.websystique.spring;
 
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
 
import com.websystique.spring.model.Employee;
import com.websystique.spring.service.EmployeeService;
 
public class AppMain {
 
    public static void main(String args[]){
        //AbstractApplicationContext  context = new AnnotationConfigApplicationContext(AppConfig.class);
        AnnotationConfigApplicationContext  context = new AnnotationConfigApplicationContext();
        context.scan("com.websystique.spring"); 
        context.refresh();
 
        EmployeeService service = (EmployeeService) context.getBean("employeeService");
 
        /*
         * Register employee using service
         */
        Employee employee = new Employee();
        employee.setName("Danny Theys");
        service.registerEmployee(employee);
         
        context.close();
    }
}

AnnotationConfigApplicationContext.scan方法會掃描指定包下的所有類,注冊所有被@Component標注的bean(實際上@configuration本身內部也是使用@component注解)到應用的上下文環境中;

另外要注意,在完成掃描操作後,refresh方法必須被調用,能保證完整的處理這些注冊類。

運行以上程序,你會看到同樣的輸出。

最後,如果使用XML配置的話,在main方法裡替換

AbstractApplicationContext  context = new AnnotationConfigApplicationContext(AppConfig.class);

AbstractApplicationContext context = new ClassPathXmlApplicationContext("app-config.xml");

會看到同樣的輸出。

本例源碼

http://websystique.com/?smd_process_download=1&download_id=793

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved