Spring之aop

1.简介

AOP:即面向切面编程

2.Aop带来的好处

让我们可以 “专心做事”
案例:
public void doSameBusiness (long lParam,String sParam){
// 记录日志
log.info(“调用 doSameBusiness方法,参数是:”+lParam);
// 输入合法性验证
if (lParam<=0){
throws new IllegalArgumentException(“xx应该大于0”);
}
if (sParam==null || sParam.trim().equals("")){
throws new IllegalArgumentException(“xx不能为空”);
}
// 异常处理
try{ …
}catch(…){
}catch(…){
}
// 事务控制
tx.commit();
}

3.工具类org.springframework.aop.framework.ProxyFactoryBean用来创建一个代理对象,在一般情况下它需要注入以下三个属性:

proxyInterfaces:代理应该实现的接口列表(List)
interceptorNames:需要应用到目标对象上的通知Bean的名字。(List)
target:目标对象 (Object)

4.案例

配置Spring 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"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd 
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
		
		
		<bean id="userBiz2" class="com.yinyi.ioc.biz.UserBizImpl1"></bean>
		<bean id="userBiz" class="com.yinyi.ioc.biz.UserBizImpl2"></bean>
		<bean id="userAction" class="com.yinyi.ioc.web.UserAction">
		<!-- <property name="uid" value="18"></property>-->
		<!-- <property name="uname" value="sb"></property> -->
		<property name="userBiz" ref="userBiz"></property> 
		<constructor-arg name="uid" value="22"></constructor-arg>
		<constructor-arg name="uname" value="zs"></constructor-arg>
		<property name="hobby">
			<list>
				<value></value>
				<value></value>
				<value>rap</value>
				<value>篮球</value>
			</list>
		</property>
	</bean>
	
	<!-- aop的知识点 -->
	<!-- 目标 -->
	<bean id="bookBiz" class="com.yinyi.aop.biz.impl.BookBizImpl"></bean>
	<!--通知 -->
	<!-- 前置通知 -->
	<bean id="myMethodBeforeAdvice" class="com.yinyi.aop.advice.MyMethodBeforeAdvice"></bean>
	<!-- 后置通知 -->
	<bean id="myAfterReturningAdvice" class="com.yinyi.aop.advice.MyAfterReturningAdvice"></bean>
	<!-- 环绕通知 -->
	<bean id="myMethodInterceptor" class="com.yinyi.aop.advice.MyMethodInterceptor"></bean>
	<!-- 异常通知 -->
	<bean id="myThrowsAdvice" class="com.yinyi.aop.advice.MyThrowsAdvice"></bean>
	<!-- 过滤通知 -->
	<bean id="myAfterReturningAdvicePlus" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
		<property name="advice" ref="myAfterReturningAdvice"></property>
		<!-- <property name="pattern" value=".*buy"></property> -->
		<property name="patterns">
			<list>
				<value>.*buy</value>
			</list>
		</property>
		
	</bean>
	
	<!-- 代理对象=目标加通知  -->
	<bean id="bookBizProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target" ref="bookBiz"></property>
		<property name="proxyInterfaces">
		<list>
			<value>com.xy.aop.biz.IBookBiz</value>
		</list>
		</property>
		<property name="interceptorNames">
		<list>
			<value>myMethodBeforeAdvice</value><!-- 前置通知 -->
			<!--<value>myAfterReturningAdvice</value> --><!-- 后置通知 -->
			<value>myAfterReturningAdvicePlus</value><!-- 过滤通知 -->
			<value>myMethodInterceptor</value><!-- 环绕通知 -->
			<value>myThrowsAdvice</value><!-- 异常通知 -->
		</list>
		</property>
	</bean>

		
				
</beans>

BookBizImpl.java

package com.yinyi.aop.biz.impl;

import com.yinyi.aop.biz.IBookBiz;
import com.yinyi.aop.exception.PriceException;

public class BookBizImpl implements IBookBiz {

	public BookBizImpl() {
		super();
	}

	public boolean buy(String userName, String bookName, Double price) {
		//通过控制台的输出方式模拟购书
		if (null == price || price <= 0) {
			throw new PriceException("book price exception");
		}
		//正常就打印
		System.out.println(userName + " buy " + bookName + ", spend " + price);
		return true;
	}
	//评论功能  
	public void comment(String userName, String comments) {
		// 通过控制台的输出方式模拟发表评论
		System.out.println(userName + " say:" + comments);
	}

}

IBookBiz接口

package com.yinyi.aop.biz;

public interface IBookBiz {
	// 购书
	public boolean buy(String userName, String bookName, Double price);

	// 发表评论
	public void comment(String userName, String comments);
}

异常处理类PriceException

package com.yinyi.aop.exception;

public class PriceException extends RuntimeException {//运行时的异常:RuntimeException

	public PriceException() {
		super();
	}

	public PriceException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
		super(message, cause, enableSuppression, writableStackTrace);
	}

	public PriceException(String message, Throwable cause) {
		super(message, cause);
	}

	public PriceException(String message) {
		super(message);
	}

	public PriceException(Throwable cause) {
		super(cause);
	}
	
}

通知:
前置通知

package com.yinyi.aop.advice;

import java.lang.reflect.Method;
import java.util.Arrays;

import org.springframework.aop.MethodBeforeAdvice;


/**
 * 
 * 前置通知
 * 买书,评论前加系统日志
 * @author yinyi
 *
 */
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {

	//arg0:哪个方法被调了  arg1:哪个类被调了
	@Override
	public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
		String clzName = arg2.getClass().getName();
		String methodName = arg0.getName();
		//哪个类的哪个方法被调用时传递的参数
		String params =Arrays.toString(arg1);
//		syso(添加日志)
//		dao.addLog(className,methodName,args,time,longTime)
		System.out.println("[系统日志]"+clzName+"."+methodName+"("+params+")");
	}

}

后置通知

package com.yinyi.aop.advice;

import java.lang.reflect.Method;
import java.util.Arrays;

import org.springframework.aop.AfterReturningAdvice;

/**
 * 后置通知
 * @author yinyi
 *
 */
public class MyAfterReturningAdvice implements AfterReturningAdvice {

	@Override
	public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
		String clzName = arg3.getClass().getName();
		String methodName = arg1.getName();
		//哪个类的哪个方法被调用时传递的参数
		String params =Arrays.toString(arg2);
		System.out.println(arg3.getClass());
		System.out.println("[后置通知(买书返利)]"+clzName+"."+methodName+"("+params+")");
	}

}

环绕通知

package com.yinyi.aop.advice;

import java.util.Arrays;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

/**
 * 环绕通知
 * @author yinyi
 *
 */
public class MyMethodInterceptor implements MethodInterceptor {

	@Override
	public Object invoke(MethodInvocation arg0) throws Throwable {
		String clzName=arg0.getThis().getClass().getName();
		String methodName=arg0.getMethod().getName();
		String params = Arrays.toString(arg0.getArguments());
		System.out.println("[环绕通知]:"+clzName+"."+methodName+"("+params+")");
		
		
		//returnValue是代理对象调用目标方法的返回值
		Object returnValue = arg0.proceed();
		System.out.println("[环绕通知]:"+clzName+"."+methodName+"("+params+")"+" 方法调用的返回值:"+returnValue);
		
		return returnValue;

	}
	
}

异常通知

package com.yinyi.aop.advice;

import org.springframework.aop.ThrowsAdvice;

import com.yinyi.aop.exception.PriceException;


/**
 * 异常通知
 * @author yinyi
 *
 */
public class MyThrowsAdvice implements ThrowsAdvice{
	public void afterThrowing( PriceException ex ) {
		System.out.println("价格输入有误,购买失败,请重新输入!!!");
	}

}

5.测试

Demo1

package com.yinyi.aop.test;


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

import com.yinyi.aop.biz.IBookBiz;

/**
 * 测试
 * @author yinyi
 *
 */
public class Demo1 {
	public static void main(String[] args) {
		ApplicationContext context = new ClassPathXmlApplicationContext("/spring-context.xml");
//		IBookBiz bean =(IBookBiz) context.getBean("bookbiz");
//		System.out.println(bean.getClass());
		IBookBiz bean = (IBookBiz) context.getBean("bookBizProxy");
//		System.out.println(bean.getClass());
		
		//报错之后,程序终止
		bean.buy("骆驼", "圣墟", 11d);
		bean.comment("骆驼", "骆驼祥子");
	}
}   

6.总结:

核心点
通知
前置通知
实现org.springframework.aop.MethodBeforeAdvice接口
买书、评论前加系统日志
后置通知
实现org.springframework.aop.AfterReturningAdvice接口
买书返利(存在bug)
环绕通知
org.aopalliance.intercept.MethodInterceptor
类似拦截器,会包括切入点,目标类前后都会执行代码。
异常通知
org.springframework.aop.ThrowsAdvice
出现异常执行系统提示,然后进行处理。价格异常为例
过滤通知(适配器)
org.springframework.aop.support.RegexpMethodPointcutAdvisor
处理买书返利的bug

本次的分享就到此结束, 感谢您的观看。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值