JavaEE開發之Spring中的依賴注入與AOP編程


上篇博客我們系統的聊了《JavaEE開發之基於Eclipse的環境搭建以及Maven Web App的創建》,並在之前的博客中我們聊了依賴注入的相關東西,並且使用Objective-C的Runtime來實現了ObjC中的依賴注入,相關博客請參考《類比Spring框架來實現OC中的依賴注入》。當然之前的博客也是使用了ObjC的Runtime的東西來實現了ObjC中的“面向切面”編程的實現方式,相關博客請移步於《ObjC中的AOP--面向切面編程》。本篇博客我們就來看一下Spring框架中的依賴注入以及AOP編程的幾種方式,當然其實現方式是使用了Java的“反射機制”,也就類似於ObjC中的Runtime了。

今天博客中所使用的Spring版本是4.3.6.RELEASE,是目前比較新的Spring版本了。而Java的版本使用的是Java8了。上篇博客我們主要聊了相關環境的創建與配置,本篇博客將不會對環境配置這些東西進行詳細的敘述。本篇博客主要聊了Spring框架中的依賴注入的實現方式,主要是通過注解以及Java配置來實現的,當然還會聊些AOP的東西。

 

一、快速創建Mava管理的Spring工程

因為本篇博客是討論關於Spring的東西,所以我們就不創建WebApp的工程了。我們使用Spring來快速的創建一個Maven管理的工程。如下所示找到File->New->Maven Project選項來創建一個新的Maven Project,具體如下所示:

  

 

下方我們選擇創建一個簡單的Maven工程,跳過模板的選擇。上篇博客我們在創建Maven工程時,是沒有選擇下方這個選項的,然后我們選擇了一個WebApp的模板。而本篇博客,我們不需要WebApp的模板,只需要一個簡單的Maven工程即可。

  

 

接着輸入組織名和工程名,如下所示。點擊Finish即可完成Maven簡單工程的創建。

  

 

下面就是我們創建好的Maven 工程的目錄結構,我們的工程代碼要放在src/main/java中,稍后會使用到。

  

創建好上述工程后,我們要在pom.xml中引入我們的Spring依賴包。下方xml就是pom.xml中的內容。我們先引入了spring-context包,如下所示:

<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.zeluli</groupId>
  <artifactId>SpringDemoWithMaven</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  
    <properties>
      <java.version>1.8</java.version>
      <spring.version>4.3.6.RELEASE</spring.version>
  </properties>
  
  <dependencies>
  <!-- Spring 核心包的引入 -->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>${spring.version}</version>
      </dependency>
      
  </dependencies>
  
  <build>
      <plugins>
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-complier-plugin</artifactId>
              <version>3.3.9</version>
              <configuration>
                  <source>${java.version}</source>
                  <target>${java.version}</target>
              </configuration>
          </plugin>
      </plugins>
  </build>
</project>

 

 

二、Spring中的依賴注入

接下來我們要來看一下Spring中的依賴注入的調用方式,該部分主要聊了兩種Spring中的依賴注入的方式。一種是注解方式,這種方式也是常用的,另一種就是Java配置類的方式。當然在早期Spring版本中是使用xml進行依賴注入的,因為xml配置的繁瑣以及不方便管理的一些特點,所以我們在工程中一般使用注解以及Java配置的形式。下方會給出注解以及Java配置的形式,並給出其使用場景。

 

1、使用注解實現依賴注入

本小部分,我們將使用注解來聲明Spring中的Bean。主要是使用@Service注解來聲明業務邏輯層(Service層)所使用的Bean,使用@Repository注解聲明數據訪問層(DAO層)使用的Bean,使用@Controller注解來聲明展現層的Bean,使用@Component來注解組件的Bean。當然這幾個注解其在底層的實現是大同小異的,其功能也是類似的,只是名稱不同。

我們可以使用Spring提供的@Autowired來聲明依賴注入的注入點,也可以使用JSR-330提供的@Inject或者JSR-250提供的@Resource注解聲明注入點。下面就來看一下這些注解的使用方式。

 

(1) @Repository

下方代碼片段就是使用@Repository注解來聲明的Bean,在數據訪問層會使用該注解來聲明DAO層的Bean。稍后我們會使用到下方的RepositoryBean。

  

 

(2) @Service

下方是我們使用@Service來聲明的Bean,在業務邏輯層,我們會使用到@Service注解進行Bean的聲明。在下方代碼段中,我們使用@Service聲明ServiceBean后,在該類中,我們注入了RepositoryBean的對象。當然使用的是@Autowired來注解的依賴對象的注入點。也就是說,在運行時,會動態的給下方的repositoryBean分配一個RepositoryBean的對象。如下所示:

  

 

(3) @Component

@Component是用來聲明組件的,也就是說你封裝了一個組件,這個組件就是使用@Component來進行注解,使其可以被注入。下方就是使用了@Component注解聲明的組件。稍后我們會在Controller中進行調用。

  

 

(4) @Controller

接下來我們就使用@Controller來聲明我們的控制器,下方的ControllerBean就是我們的控制器類,當然此處我們使用@Controller進行的注解。然后在該控制器類中,我們使用了@Autowired注解來注入ServiceBean和ComponentBean的對象,然后在下方相應的方法中進行了使用。

  

 

(5)、創建Spring的配置文件

接下來我們將創建Spring的配置文件,因為Spring可以通過此配置文件讀取一些上下文的信息。當然,Spring的配置文件其實就是一個Java類,然后我們使用@Configuration進行修飾即可。而@ComponentScan("包名")負責指定組件所在的包,也就是說設置完該項后,Spring會自動掃描該包下的@Component、@Service、@Repository、@Controller這些注解。

  

 

(6)、創建Main函數進行測試

上面一些列的Bean已經創建完畢,接下來,我們要創建我們測試用的Main函數了。首先我們使用注解配置上下文AnnotationConfigApplicationContext對象來從Java的配置文件中獲取Spring的上下文。然后獲取Controller Bean,下方是調用Controller Bean的相應的方法。最后再將調用的資源關閉掉即可。

  

 

(7)、運行結果

上述實現完Main方法后,接下來我們就可以對其運行並看起運行效果了。具體運行結果如下所示:

  

 

 

2、Java配置

上面一部分是使用Spring中提供的相關注解來聲明的各種類型的Bean。接下來我們就在Spring的配置文件來聲明相關的Bean,當然在Java配置文件中聲明的Bean一般是全局的,也就是說一些Bean要定義成全局的對象的話,我們就在Java配置中來進行Bean的聲明。例如一些公共的組件的Bean,我們就可以將其放入到Java的配置文件中。接下來我們就來看一下Spring配置文件中是如何來聲明Bean的。

 

(1)、創建Java配置使用的類

首先我們來創建一個類,此處我們命名為JavaConfigBean。然后我們要在Spring的配置文件中將其聲明為Bean。我們可以看出,下方類就是一個普通的Java類,該類中並沒有使用任何的注解進行修飾。

  

 

(2)、在Spring配置文件中聲明Bean

接下來我們將會在Spring的配置文件中使用@Bean注解將上述的JavaConfigBean聲明為Bean對象。下方代碼段就是Spring配置文件中的內容,其中的createJavaConfigBean()方法負責生成上述類的對象。其中我們使用@Bean注解聲明該方法,該方法會返回JavaConfigBean類的對象。在使用JavaConfigBean的對象時,會將下方生成的對象注入到相應的點上。

  

 

(3)、創建依賴JavaConfigBean的Controller

接下來我們就來創建一個Controller類,在該類中我們來使用JavaConfigBean的對象。下方就是我們創建的ControllerBean的類中的具體內容,其中使用了@Autowired注解來聲明的注入點,如下所示:

  

 

(4)、創建Main函數以及測試結果

接下來我們就該創建一個Main函數來進行測試了。在Main函數中依然是調用了ControllerBean的相關方法,如下所示:

  

 

 

 

三、面向切面編程--(Aspect Oriented Programming)

在前段時間發布的博客中,我們已經使用了ObjC的Runtime來演示了AOP編程的實現原理。在Java中利用了Java的“反射機制”來實現的。其實在運行時,我們通過方法體的交換就可以實現AOP編程。Spring中的AOP編程也不例外,也是通過方法交換來實現的,本篇博客,我們就來看一下Spring框架中是如何使用AOP編程的。本部分給出了Spring框架中兩種AOP編程的調用方案,一種是基於注解式的攔截方式,另一種是基於方法式的攔截。

下方將會分別給出這兩種AOP編程實現的兩種方式。在基於注解式的攔截方式中,我們需要為切點方法添加注解,而方法式攔截則不需要在切點方法上做任何操作。

 

1、引入Spring的AOP依賴包和AspectJ依賴包

下方的XML內容就是我們要在pom.xml添加的相關依賴配置,下方我們添加了spring-aop以及aspectj的依賴。aspectj也是一個Java的面向切面編程的依賴包。我們要做的東西也依賴於aspectj。具體的依賴包的引入如下所示:

       <!-- spring aop支持 -->
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-aop</artifactId>
          <version>4.3.6.RELEASE</version>
      </dependency>

      <!-- aspectj支持 -->
      <dependency>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjrt</artifactId>
          <version>1.8.9</version>
      </dependency>

 

 

2、基於注解的AOP

接下來我們將實現基於注解式的AOP實現,下方我們將創建AOP使用的注解,切面類、被切面的Controller、Spring配置文件以及測試用的Main函數。下方是基於注解的AOP的具體實現。

(1)、創建AOP使用的注解

首先我們先創建一個注解,該注解會在切入點中進行使用。選擇我們相應的package,然后右鍵單擊->New->Annotation來創建一個注解。

  

該注解中的內容比較簡單,具體內容如下所示:

package com.zeluli.aop.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Action {
}

 

(2)、創建切面切入的Controller

接下來我們就來創建一個切面切入的Controller,此處我們將該類命名為AnnotationController。在該Controller中相應方法上,我們使用上述我們創建的@Action注解來進行聲明,將其聲明為我們切面的切入點。具體如下所示:

  

 

(3)、編寫切面類

定義好聲明切點的注解@Action以及被切入的Controller后,接下來,我們就該創建切面類了。下方創建的LogAspect類就是用來切入AnnotationController類的切面類。具體內容如下所示。

我們使用@Aspect注解將LogAspect類聲明為切面,然后使用@Component注解將其聲明為組件。之所以將其聲明為組件,是因為我們可以將該切面切入到好多類中。然后我們使用@Pointcut注解來指定切入點,@Pointcut參數就是我們上面創建的注解@Action。也就是說使用@Action修飾的方法就是我們的切入點。使用@Before注解來聲明在切點之前執行的方法,使用@After注解來聲明在切點之后執行的方法。下方就是LogAspect類的具體內容。

  

 

(4)、創建Spring的配置文件

接着我們要創建配置類,在配置類中我們要開啟AspectJ的自動代理,如下所示。

  

 

(5)、創建Main函數進行測試

接下來,我們就開始測試了。Main方法比較簡單,與上面的Main方法大同小異。主要是調用AnnotationConfigApplicationContext來從配置文件中加載上下文,然后根據上下文獲取AnnotationController的對象,然后調用testMethod()方法,最后將上下文進行關閉即可。

public class Main {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext aopContext = new AnnotationConfigApplicationContext(AopConfig.class);
        AnnotationController controller = aopContext.getBean(AnnotationController.class);
        controller.testMethod();
        aopContext.close();
    }
}

 

下方截圖就是上述Main方法的運行結果,可見,在testMethod()方法調用之前會執行切片的@Before方法,testMethod()方法執行之后會執行@After方法。具體結果如下所示:

  

 

3、基於方法的AOP

上面我們聊了基於注解攔截的切面,接下來我們就來看一下基於方法的切面。也就是說在該部分,我們不會創建注解。直接創建LogAspect切面即可。下方這個LogAspect切面就是基於方法的切面。其中在@Before或者@After注解后邊跟着一串字符串,該字符串就是切入點所在類。如下所示。

  

上述切面的運行效果與注解切面的運行效果一致,在此就不做過多贅述了。

 

本篇博客就先到此,上述相關代碼在github上的分享地址為:https://github.com/lizelu/SpringDemo


免責聲明!

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



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