Spring_AOP(XML)

AOP思想:横向重复、纵向抽取

2.底层实现:

Spring的AOP底层使用两种代理机制

      (1) JDK的动态代理:针对实现了接口的类产生代理

      (2)Cglib的动态代理:针对没有实现接口的类产生代理、应用的是底层的字节码增强的技术生成当前类的子类对象

3.相关术语

       (1)Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在Spring中这些点指的是方法,因为Spring只支持方法类型的连接点(可以被切入的点)

      (2)Pointcut(切入点):所谓切入点是指对哪些Jonpoint进行拦截的定义(已经被切入的点)

      (3)Advice(通知/增强):所谓通知是指拦截到Joinpoint之后所做的事情就是通知。通知分为前置通知、后置通知、异常通知、最终通知、环绕通知(切面要完成的功能)

      (4)Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下,Introduction可以在运行期为类动态地添加一些方法或者Field。

      (5)Aspect(切面):是切入点和通知(引介)的结合

扫描二维码关注公众号,回复: 11385197 查看本文章

      (6)Target(目标对象):代理的目标对象

      (7)Proxy(代理):一个类被AOP织入增强后,就产生一个结果代理类

      (8)Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程,spring采用动态代理织入,而Aspect采用编译时期织入和类装载期织入

4.AOP实例

 (1)创建Web项目(项目结构)

       

 (2)导入jar

 (3)加入日志配置(log4j.properties)

# Global logging configuration
log4j.rootLogger=info, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

(4)先创建接口->创建实现类

package com.linixn.spring.service;

public interface UserService{
		//增加
		public void save();
		//删除	
		public void delete();
		//修改
		public void update();
		//查询
		public void select();

}
package com.linixn.spring.service;

public class UserServiceImpl  implements UserService {
		@Override
		public void save() {
			System.out.println("增加");
		}
	
		@Override
		public void delete() {
			System.out.println("删除");
		}
	
		@Override
		public void update() {
			System.out.println("更新");
		}
	
		@Override
		public void select() {
			System.out.println("查询");
		}
}

  (5)编写通知

           前置通知:在目标方法之前调用

           后置通知(出现异常就不调用):在目标方法之后调用

          后置通知(无论是否出现异常都调用):在目标方法之后调用

           环绕通知:在目标方法之前、后调用

           异常通知:出现异常则调用

package com.linixn.spring.advice;

import org.aspectj.lang.ProceedingJoinPoint;

public class TransactionAdive {
	//	前置通知:在目标方法之前调用
	//	后置通知(出现异常就不调用):在目标方法之后调用
	//	后置通知(无论是否出现异常都调用):在目标方法之后调用
	//	环绕通知:在目标方法之前、后调用
	//	异常通知:出现异常则调用
	public void before() {
		System.out.println("前置通知被执行");
	}
	public void afterReturning() {
		System.out.println("后置置通知被执行(出现异常不调用)");
	}
	public void after() {
		System.out.println("后置通知(无论是否出现异常都调用)");
	}
	public void afterException() {
		System.out.println("异常通知:出现异常则调用");
	}
	public Object around(ProceedingJoinPoint point) throws Throwable {
		System.out.println("环绕通知之前");
		Object proceed= point.proceed();
		System.out.println("环绕通知之后");
		return proceed;
	}
}

 (6)配置织入,将通知织入目标对象

     aop:pointcut

AOP配置切点的正则表达式
符号 含义
. 匹配除换行外的所有单个字符
* 匹配前面的字符0次或者多次
+ 匹配前面的字符1次或者多次
匹配前面的字符0次或者1次
^ 匹配字符开始
$ 匹配字符结束
x|y 匹配x或y
[xyz] xyz其中一个
{n} 匹配n次
{n,} 匹配至少n次
{n,m} 匹配n次到m次
\ 转义字符
<?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:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:centext="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
		http://www.springframework.org/schema/context
		http://www.springframework.org/schema/context/spring-context-4.2.xsd
		http://www.springframework.org/schema/aop
		http://www.springframework.org/schema/aop/spring-aop-4.2.xsd ">
		<!-- 目标对象 -->
		<bean name="userService" class="com.linixn.spring.service.UserServiceImpl"></bean>
		<!-- 通知对象 -->
		<bean name="transactionAdvice" class="com.linixn.spring.advice.TransactionAdive"></bean>
		<!-- 将通知对象织入目标对象 -->
		<aop:config>
			<!-- 选择切入点 -->
			<!-- 方法加返回值 -->
			<aop:pointcut expression="execution(public void com.linixn.spring.service.UserService.update() )" id="pointcut"/>
			<aop:aspect ref="transactionAdvice">
				<!-- 前置切入 -->
				<aop:before method="before" pointcut-ref="pointcut"/>
				<!-- 无论是否出现异常都会调用 -->
				<aop:after method="after" pointcut-ref="pointcut"/>
				<!-- 出现异常不调用 -->
				<aop:after-returning method="afterReturning" pointcut-ref="pointcut"/>
				<aop:around method="around" pointcut-ref="pointcut"/>
				<aop:after-throwing method="afterException" pointcut-ref="pointcut"/>
			</aop:aspect>
		</aop:config>
</beans>

 (7)测试

   (1)无异常测试

package com.linixn.spring.service.test;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.linixn.spring.service.UserService;

//创建容器
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserTest {
	@Resource(name="userService")
	private UserService userSer;
	
	@Test
	public void UserTest1() {
		userSer.update();
	}

}

 (2)出现异常测试

           修改updata()方法加入 int a=1/0;

          测试结果

          

猜你喜欢

转载自blog.csdn.net/weixin_45460315/article/details/105027525