JavaEE开发之Spring中的依赖注入与AOP编程

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaEE开发之Spring中的依赖注入与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)
@Documentedpublic @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注解后边跟着一串字符串,该字符串就是切入点所在类。如下所示。

  技术分享


以上是关于JavaEE开发之Spring中的依赖注入与AOP编程的主要内容,如果未能解决你的问题,请参考以下文章

Spring基础知识之依赖注入

Spring框架

Spring IOC

JavaEE目录

Spring_Ioc容器

Spring 之 控制反转(IoC), 依赖注入(DI)和面向切面(AOP)