篇博客我們系統(tǒng)的聊了《JavaEE開發(fā)之基于Eclipse的環(huán)境搭建以及Maven Web App的創(chuàng)建》,并在之前的博客中我們聊了依賴注入的相關(guān)東西,并且使用Objective-C的Runtime來實(shí)現(xiàn)了ObjC中的依賴注入,相關(guān)博客請參考《類比Spring框架來實(shí)現(xiàn)OC中的依賴注入》。當(dāng)然之前的博客也是使用了ObjC的Runtime的東西來實(shí)現(xiàn)了ObjC中的“面向切面”編程的實(shí)現(xiàn)方式,相關(guān)博客請移步于《ObjC中的AOP--面向切面編程》。本篇博客我們就來看一下Spring框架中的依賴注入以及AOP編程的幾種方式,當(dāng)然其實(shí)現(xiàn)方式是使用了Java的“反射機(jī)制”,也就類似于ObjC中的Runtime了。

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

 

一、快速創(chuàng)建Mava管理的Spring工程

因?yàn)楸酒┛褪怯懻撽P(guān)于Spring的東西,所以我們就不創(chuàng)建WebApp的工程了。我們使用Spring來快速的創(chuàng)建一個(gè)Maven管理的工程。如下所示找到File->New->Maven Project選項(xiàng)來創(chuàng)建一個(gè)新的Maven Project,具體如下所示:

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

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

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

接著輸入組織名和工程名,如下所示。點(diǎn)擊Finish即可完成Maven簡單工程的創(chuàng)建。

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

下面就是我們創(chuàng)建好的Maven 工程的目錄結(jié)構(gòu),我們的工程代碼要放在src/main/java中,稍后會使用到。

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

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

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

<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>

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

 

二、Spring中的依賴注入

接下來我們要來看一下Spring中的依賴注入的調(diào)用方式,該部分主要聊了兩種Spring中的依賴注入的方式。一種是注解方式,這種方式也是常用的,另一種就是Java配置類的方式。當(dāng)然在早期Spring版本中是使用xml進(jìn)行依賴注入的,因?yàn)閤ml配置的繁瑣以及不方便管理的一些特點(diǎn),所以我們在工程中一般使用注解以及Java配置的形式。下方會給出注解以及Java配置的形式,并給出其使用場景。

 

1、使用注解實(shí)現(xiàn)依賴注入

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

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

 

(1) @Repository

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

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

(2) @Service

下方是我們使用@Service來聲明的Bean,在業(yè)務(wù)邏輯層,我們會使用到@Service注解進(jìn)行Bean的聲明。在下方代碼段中,我們使用@Service聲明ServiceBean后,在該類中,我們注入了RepositoryBean的對象。當(dāng)然使用的是@Autowired來注解的依賴對象的注入點(diǎn)。也就是說,在運(yùn)行時(shí),會動態(tài)的給下方的repositoryBean分配一個(gè)RepositoryBean的對象。如下所示:

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

(3) @Component

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

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

(4) @Controller

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

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

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

接下來我們將創(chuàng)建Spring的配置文件,因?yàn)镾pring可以通過此配置文件讀取一些上下文的信息。當(dāng)然,Spring的配置文件其實(shí)就是一個(gè)Java類,然后我們使用@Configuration進(jìn)行修飾即可。而@ComponentScan("包名")負(fù)責(zé)指定組件所在的包,也就是說設(shè)置完該項(xiàng)后,Spring會自動掃描該包下的@Component、@Service、@Repository、@Controller這些注解。

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

(6)、創(chuàng)建Main函數(shù)進(jìn)行測試

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

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

(7)、運(yùn)行結(jié)果

上述實(shí)現(xiàn)完Main方法后,接下來我們就可以對其運(yùn)行并看起運(yùn)行效果了。具體運(yùn)行結(jié)果如下所示:

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

 

2、Java配置

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

 

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

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

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

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

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

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

(3)、創(chuàng)建依賴JavaConfigBean的Controller

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

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

(4)、創(chuàng)建Main函數(shù)以及測試結(jié)果

接下來我們就該創(chuàng)建一個(gè)Main函數(shù)來進(jìn)行測試了。在Main函數(shù)中依然是調(diào)用了ControllerBean的相關(guān)方法,如下所示:

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

 

 

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

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

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

 

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

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

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

       <!-- 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>

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

 

2、基于注解的AOP

接下來我們將實(shí)現(xiàn)基于注解式的AOP實(shí)現(xiàn),下方我們將創(chuàng)建AOP使用的注解,切面類、被切面的Controller、Spring配置文件以及測試用的Main函數(shù)。下方是基于注解的AOP的具體實(shí)現(xiàn)。

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

首先我們先創(chuàng)建一個(gè)注解,該注解會在切入點(diǎn)中進(jìn)行使用。選擇我們相應(yīng)的package,然后右鍵單擊->New->Annotation來創(chuàng)建一個(gè)注解。

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

該注解中的內(nèi)容比較簡單,具體內(nèi)容如下所示:

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

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)
@Documentedpublic @interface Action {
}

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

(2)、創(chuàng)建切面切入的Controller

接下來我們就來創(chuàng)建一個(gè)切面切入的Controller,此處我們將該類命名為AnnotationController。在該Controller中相應(yīng)方法上,我們使用上述我們創(chuàng)建的@Action注解來進(jìn)行聲明,將其聲明為我們切面的切入點(diǎn)。具體如下所示:

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

(3)、編寫切面類

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

我們使用@Aspect注解將LogAspect類聲明為切面,然后使用@Component注解將其聲明為組件。之所以將其聲明為組件,是因?yàn)槲覀兛梢詫⒃撉忻媲腥氲胶枚囝愔?。然后我們使?span style="margin: 0px; padding: 0px; color: rgb(255, 0, 0);">@Pointcut注解來指定切入點(diǎn),@Pointcut參數(shù)就是我們上面創(chuàng)建的注解@Action。也就是說使用@Action修飾的方法就是我們的切入點(diǎn)。使用@Before注解來聲明在切點(diǎn)之前執(zhí)行的方法,使用@After注解來聲明在切點(diǎn)之后執(zhí)行的方法。下方就是LogAspect類的具體內(nèi)容。

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

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

接著我們要創(chuàng)建配置類,在配置類中我們要開啟AspectJ的自動代理,如下所示。

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

(5)、創(chuàng)建Main函數(shù)進(jìn)行測試

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

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

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();
    }
}

iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

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

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

 

3、基于方法的AOP

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

  iOS培訓(xùn),Swift培訓(xùn),蘋果開發(fā)培訓(xùn),移動開發(fā)培訓(xùn)

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

 

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

作者:青玉伏案 
出處:http://www.cnblogs.com/ludashi/ 
本文版權(quán)歸作者和共博客園共有,歡迎轉(zhuǎn)載,但未經(jīng)作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接,否則保留追究法律責(zé)任的權(quán)利。 
如果文中有什么錯(cuò)誤,歡迎指出。以免更多的人被誤導(dǎo)。

http://www.cnblogs.com/ludashi/p/6541925.html