Spring AOP

1.AOP简介

AOP 即 Aspect Oriented Program 面向切面编程
首先,在面向切面编程的思想里面,把功能分为核心业务功能,和周边功能
所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务
所谓的周边功能,比如性能统计,日志,事务管理等等

周边功能在Spring的面向切面编程AOP思想里,即被定义为切面

在面向切面编程AOP的思想里面,核心业务功能和切面功能分别独立开发
然后把切面功能和核心业务功能 “编织” 在一起,这就叫AOP

2.什么是advice,joinpoint ,pointcut

  1. AOP中的一个重要术语是advance。它是特定join-point上某个aspect 所采取的操作。
  2. Joinpoint是程序的执行点,例如方法的执行或异常的处理。在Spring AOP中,Joinpoint始终表示方法执行。
  3. pointcut是匹配Joinpoint的表达式
  4. advice与pointcut表达式相关联,并在pointcut匹配的任何连接点处运行。
  5. Spring默认使用AspectJ切入点表达式语言。

3.AOP的advice类型

  1. Before advice:在连接点之前执行但不能阻止执行流程进入连接点议(除非它抛出异常)。
  2. After returning advice:在连接点正常完成后执行:例如,如果方法返回而且不抛出异常就会执行。
  3. After throwing advice:如果方法通过抛出异常退出,则执行。
  4. After (finally) advice:无论连接点退出的方式(正常或异常返回),都要执行。
  5. Around advice:围绕连接点,例如方法调用。这是最有力的advice。around通知可以在方法调用之前和之后执行自定义行为。它还负责选择是继续加入点还是通过返回自己的返回值或抛出异常来加速advice的方法执行。

2.AOP基于XML的配置(已不用)

1.声明一个aspect

使用 <aop:aspect> 元素声明一个aspect。aspect使用ref引用bean,id自取。

<bean id="loggerAspect" class="com.how2java.aspect.LoggerAspect"/>

<aop:config>
	<!-- 指定左边的辅助功能 然后通过aop:config把业务对象与辅助功能编织在一起。 -->
	<aop:aspect id="logAspect" ref="loggerAspect">
		······
	</aop:aspect>
</aop:config>

2.声明一个切入点(pointcut)

一个切入点有助于确定使用不同advice执行的连接点(即方法)。
在处理基于配置的 XML 架构时,切入点将会按照如下所示定义:

<aop:config>
	<aop:aspect id="logAspect" ref="loggerAspect">
		<aop:pointcut id="loggerCutpoint" 
			expression=
			"execution(* com.how2java.service.ProductService.*(..)) "/>
		······
	</aop:aspect>
</aop:config>

"execution( com.how2java.service.ProductService.(…)) "
这表示对满足如下条件的方法调用,进行切面操作:
* 返回任意类型
com.how2java.service.ProductService.* 包名以 com.how2java.service.ProductService 开头的类的任意方法
(…) 参数是任意数量和类型

3.声明advice

advice有五个

<!-- log()是切片类内的方法 -->
<aop:around pointcut-ref="loggerCutpoint" method="log"/>

4.总体:

</bean>    
<!-- 声明日志切面 -->
<bean id="loggerAspect" class="com.how2java.aspect.LoggerAspect"/>
    
<aop:config>
	<aop:aspect id="logAspect" ref="loggerAspect">
		<aop:pointcut id="loggerCutpoint" 
			expression=
			"execution(* com.how2java.service.ProductService.*(..)) "/>
			
		<!-- log()是切片类内的方法 -->
		<aop:around pointcut-ref="loggerCutpoint" method="log"/>
	</aop:aspect>
</aop:config>

再举例子:
这里是Logging.java文件的内容。这实际上是aspect模块的一个示例,它定义了在各个点调用的方法。

package com.tutorialspoint;
public class Logging {
   /** 
    * This is the method which I would like to execute
    * before a selected method execution.
    */
   public void beforeAdvice(){
      System.out.println("Going to setup student profile.");
   }
   /** 
    * This is the method which I would like to execute
    * after a selected method execution.
    */
   public void afterAdvice(){
      System.out.println("Student profile has been setup.");
   }
   /** 
    * This is the method which I would like to execute
    * when any method returns.
    */
   public void afterReturningAdvice(Object retVal){
      System.out.println("Returning:" + retVal.toString() );
   }
   /**
    * This is the method which I would like to execute
    * if there is an exception raised.
    */
   public void AfterThrowingAdvice(IllegalArgumentException ex){
      System.out.println("There has been an exception: " + ex.toString());   
   }  
}

的英文下面Student.java文件的内容:

package com.tutorialspoint;
public class Student {
   private Integer age;
   private String name;
   public void setAge(Integer age) {
      this.age = age;
   }
   public Integer getAge() {
      System.out.println("Age : " + age );
      return age;
   }
   public void setName(String name) {
      this.name = name;
   }
   public String getName() {
      System.out.println("Name : " + name );
      return name;
   }  
   public void printThrowException(){
       System.out.println("Exception raised");
       throw new IllegalArgumentException();
   }
}

的英文下面MainApp.java文件的内容:

package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = 
             new ClassPathXmlApplicationContext("Beans.xml");
      Student student = (Student) context.getBean("student");
      student.getName();
      student.getAge();      
      student.printThrowException();
   }
}

下面是配置文件Beans.xml:

<?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:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

   <aop:config>
      <aop:aspect id="log" ref="logging">
         <aop:pointcut id="selectAll" 
         expression="execution(* com.tutorialspoint.*.*(..))"/>
         <aop:before pointcut-ref="selectAll" method="beforeAdvice"/>
         <aop:after pointcut-ref="selectAll" method="afterAdvice"/>
         <aop:after-returning pointcut-ref="selectAll" 
                              returning="retVal"
                              method="afterReturningAdvice"/>
         <aop:after-throwing pointcut-ref="selectAll" 
                             throwing="ex"
                             method="AfterThrowingAdvice"/>
      </aop:aspect>
   </aop:config>

   <!-- Definition for student bean -->
   <bean id="student" class="com.tutorialspoint.Student">
      <property name="name"  value="Zara" />
      <property name="age"  value="11"/>      
   </bean>

   <!-- Definition for logging aspect -->
   <bean id="logging" class="com.tutorialspoint.Logging"/> 

</beans>

一旦你已经完成的创建了源文件和bean配置文件,让我们运行一下应用程序。如果你的应用程序一切都正常的话,这将会输出以下消息:

Going to setup student profile.
Name : Zara
Student profile has been setup.
Returning:Zara
Going to setup student profile.
Age : 11
Student profile has been setup.
Returning:11
Going to setup student profile.
Exception raised
Student profile has been setup.
There has been an exception: java.lang.IllegalArgumentException
.....
other exception content

3.AOP基于注解@AspectJ的配置

举例子:
这里是 Logging.java 文件的内容。这实际上是 aspect 模块的一个示例,它定义了在各个点调用的方法。注释写的很清楚
这里用一个selectAll匹配了所有方法,然后对selectAll进行操作。也可以对每个方法单独匹配

package com.tutorialspoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
@Aspect //!!!!
public class Logging {
   /** Following is the definition for a pointcut to select
    *  all the methods available. So advice will be called
    *  for all the methods.
    */
   @Pointcut("execution(* com.tutorialspoint.*.*(..))")
   private void selectAll(){}
   /** 
    * This is the method which I would like to execute
    * before a selected method execution.
    */
   @Before("selectAll()")
   public void beforeAdvice(){
      System.out.println("Going to setup student profile.");
   }
   /** 
    * This is the method which I would like to execute
    * after a selected method execution.
    */
   @After("selectAll()")
   public void afterAdvice(){
      System.out.println("Student profile has been setup.");
   }
   /** 
    * This is the method which I would like to execute
    * when any method returns.
    */
   @AfterReturning(pointcut = "selectAll()", returning="retVal")
   public void afterReturningAdvice(Object retVal){
      System.out.println("Returning:" + retVal.toString() );
   }
   /**
    * This is the method which I would like to execute
    * if there is an exception raised by any method.
    */
   @AfterThrowing(pointcut = "selectAll()", throwing = "ex")
   public void AfterThrowingAdvice(IllegalArgumentException ex){
      System.out.println("There has been an exception: " + ex.toString());   
   }  
}

下面是 Student.java 文件的内容:

package com.tutorialspoint;

import org.springframework.stereotype.Component;
//@Component 表示这是一个bean,由Spring进行管理
@Component
public class Student {
   private Integer age;
   private String name;
   public void setAge(Integer age) {
      this.age = age;
   }
   public Integer getAge() {
      System.out.println("Age : " + age );
      return age;
   }
   public void setName(String name) {
      this.name = name;
   }
   public String getName() {
      System.out.println("Name : " + name );
      return name;
   }
   public void printThrowException(){
      System.out.println("Exception raised");
      throw new IllegalArgumentException();
   }
}

下面是 MainApp.java 文件的内容:

package com.tutorialspoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = 
             new ClassPathXmlApplicationContext("Beans.xml");
      Student student = (Student) context.getBean("student");
      student.getName();
      student.getAge();     
      student.printThrowException();
   }
}

下面是配置文件 Beans.xml:

<?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:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
	<!--找到被注解了的切面类,进行切面配置-- >
    <aop:aspectj-autoproxy/>

   <!-- Definition for student bean -->
   <bean id="student" class="com.tutorialspoint.Student">
      <property name="name"  value="Zara" />
      <property name="age"  value="11"/>      
   </bean>

   <!-- Definition for logging aspect -->
   <bean id="logging" class="com.tutorialspoint.Logging"/> 

</beans>

一旦你已经完成的创建了源文件和 bean 配置文件,让我们运行一下应用程序。如果你的应用程序一切都正常的话,这将会输出以下消息:

Going to setup student profile.
Name : Zara
Student profile has been setup.
Returning:Zara
Going to setup student profile.
Age : 11
Student profile has been setup.
Returning:11
Going to setup student profile.
Exception raised
Student profile has been setup.
There has been an exception: java.lang.IllegalArgumentException
.....
other exception content

我们来看其中的一段:

Going to setup student profile.
Name : Zara
Student profile has been setup.
Returning:Zara

这段输出是当我们调用getName()方法时输出的。

@Before("selectAll()")
   public void beforeAdvice(){
      System.out.println("Going to setup student profile.");
   }

在所有切入点之前调用,输出"Going to setup student profile."

public String getName() {
	System.out.println("Name : " + name );
    return name;
}

执行方法,输出Name

@After("selectAll()")
public void afterAdvice(){
	System.out.println("Student profile has been setup.");
}

在所有切入点之后调用,输出"Student profile has been setup."

@AfterReturning(pointcut = "selectAll()", returning="retVal")
public void afterReturningAdvice(Object retVal){
	System.out.println("Returning:" + retVal.toString() );
}

在方法返回后调用(有返回值才会调用)。输出"Returning:" + retVal.toString()。retVal是返回值,可以配置。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
该资源内项目源码是个人的课程设计、毕业设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 该资源内项目源码是个人的课程设计,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! ## 项目备注 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值