Spring——(五)AOP面向切面

2018-11-02 02:53:00     

一、概念

AOP 即Aspect Oriented Program面向切面编程

  • 在面向切面编程的思想里面,把功能分为核心业务功能周边功能 所谓的核心业务,比如登陆,增加数据,删除数据都叫核心业务。所谓的周边功能,比如性能统计,日志,事务管理等等
  • 周边功能在AOP思想里,定义为切面(Aspect)
  • 在面向切面编程AOP的思想里面,核心业务功能和周边功能分别独立开发然后把切面功能和核心业务功能 编织在一起,这就叫AOP

二、Aspect的前置、最终通知

  1. 新建SpringTest03项目,在service包下新建一个核心业务Student类注明其主要功能。代码如下:

package service;

/**
 * @author bounds
 *	定义一个核心功能
 */
public class Student {
	/**
	 * 赛跑
	 */
	public void run(String name){
		System.out.println(name+"参加100米赛跑。。。");
	}
}

2.继续在service包下新建一个切面Aspect类定义其主要功能,代码如下:

package service;

/**
 * @author bounds 
 * 定义一个切面
 */
public class Aspect {

	/**
	 * 开始
	 */
	public void start() {
		System.out.println("计时开始。。。");
	}

	/**
	 * 结束
	 */
	public void end() {
		System.out.println("计时结束。。。");
	}
}

3.找到spring的配置文件,在beans里边引入aop命名空间对AOP功能的支持,装配bean以及配置AOP,配置如下:

<?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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context 
		http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/aop 
		http://www.springframework.org/schema/aop/spring-aop.xsd">
	<!-- 装配Bean -->
	<bean name="student" class="service.Student"></bean>
	<bean name="aspect" class="service.Aspect"></bean>
	<!-- 配置AOP -->
	<aop:config>
		<!-- 定义aspect切面 -->
		<aop:aspect id="aspect" ref="aspect">
			<!-- 用来声明切入点 作为被监视的对象 -->
			<aop:pointcut id="pointCut" expression="execution(* service.Student.*(..))" />
			<!-- 定义aspect前置通知 -->
			<aop:before pointcut-ref="pointCut" method="start" />
			<!-- 定义aspect最终通知 -->
			<aop:after pointcut-ref="pointCut" method="end" />
		</aop:aspect>
	</aop:config>
</beans>
  • execution(* service.Student.*(..))这表示对满足如下条件的方法调用,进行切面操作:包名以service.Student开头的类的任意方法(..)参数是任意数量和类型。

4.找到maven的pom.xml文件,在里边添加aspect的jar包配置:如下代码:

	<dependency>
		<groupId>org.aspectj</groupId>
		<artifactId>aspectjweaver</artifactId>
		<version>1.8.9</version>
	</dependency>

5.在test包下新建TestAOP测试类,代码如下:

package test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import service.Student;

/**
 * @author bounds
 *	测试类
 */
public class TestAOP {
	@Test
	public void testOne(){
		ApplicationContext context=new ClassPathXmlApplicationContext("classpath:spring/application-config.xml");
		Student student=(Student)context.getBean("student",Student.class);
		student.run("Bounds");
		((ClassPathXmlApplicationContext)context).close();
	}
}

6.使用JUnit运行测试,打印结果如下:

计时开始。。。
Bounds参加100米赛跑。。。
计时结束。。。

三、环绕通知

1.修改Aspect类合并切面功能,如下代码:

package service;

import org.aspectj.lang.ProceedingJoinPoint;

/**
 * @author bounds 
 * 定义一个切面
 */
public class Aspect {

	public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
		System.out.println("计时开始。。。");
		//可替换被监视对象的形参,这是around最厉害的地方
		Object object =joinPoint.proceed(new Object[]{"Cubi"});
		System.out.println("计时结束。。。");
		return object;
	}
}

2.修改spring的配置文件定义一个环绕通知,如下代码:

<?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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="http://www.springframework.org/schema/beans 
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context 
		http://www.springframework.org/schema/context/spring-context.xsd
		http://www.springframework.org/schema/aop 
		http://www.springframework.org/schema/aop/spring-aop.xsd">
	<!-- 装配Bean -->
	<bean name="student" class="service.Student"></bean>
	<bean name="aspect" class="service.Aspect"></bean>
	<!-- 配置AOP -->
	<aop:config>
		<!-- 定义aspect切面 -->
		<aop:aspect id="aspect" ref="aspect">
			<!-- 用来声明切入点 作为被监视的对象 -->
			<aop:pointcut id="pointCut" expression="execution(* service.Student.*(..))" />
			<!-- 定义aspect环绕通知 -->
			<aop:around pointcut-ref="pointCut" method="around" />
		</aop:aspect>
	</aop:config>
</beans>

3.使用JUnit运行测试,打印结果如下:

计时开始。。。
Cubi参加100米赛跑。。。
计时结束。。。
  • 由测试类传入的参数Bounds在经过环绕通知时被替换成Cubi了

四、总结

  • before前置通知:在方法执行前执行,如果通知抛出异常,阻止方法运行
  • after最终通知:方法执行完毕后执行,无论方法中是否出现异常
  • around环绕通知:十分强大,可以做任何事情,方法执行前后分别执行,可以阻止方法的执行,必须手动执行目标方法

ps:本篇博客源码下载链接:https://pan.baidu.com/s/19Wypw40Om55vKYBqSxaHlg 密码:1e2n
Spring——(四)注解方式 IOC/DI

一、摘要前面讲解IOC DI都是通过xml文件进行配置的,这种配置对小型项目是看不出什么问题,但是在大型项目上,就会觉得配置xml文件臃肿又麻烦了。因此,不再推荐使用xml的方式去装配Bean而是考虑使用注解的方式去装配Bean两种注解配置:自动装配:对注入对象行为的注解组件扫描:对Bean的注解二、自动装配 导入上一篇博客Spring——(二)IOC控制反转/DI依赖注入的源代码作为这篇博客的继续 修改xml配置文件,在xml配置文件中加上<context:annotation-config/>并且注释掉DI对象注入,如下配置:在Student实体类中的private Teacher teacher;前加上@Autowired注解,代码如下:package entity; import org.springframework.beans.factory.annotation.Autowired; public class Student { private int id; private String name; @Autowired private

Spring——(六)注解方式AOP

一、摘要本篇博客使用上一篇博客的源代码,对上一篇博客进行改造:Spring——(四)AOP面向切面注解方式核心业务功能注解方式周边功能(切面)注解方式测试二、注解方式AOP1.使用@Component注解Student类@Component表示这是一个bean,由Spring进行管理。代码如下:package service; import org.springframework.stereotype.Component; /** * @author bounds * 定义一个核心功能 */ @Component("student") public class Student { /** * 赛跑 */ public void run(String name){ System.out.println(name+"参加100米赛跑。。。"); } } 2.@Aspect注解AsptectTest类表示这是一个切面@Around(value="execution(* service.Student.*(..))")表示对Student类中的所有方法定义为切面。代码如下:package

 发表评论