关于Spring核心原理Aop的几种实现方式

来源:互联网 发布:贵州广电网络网上缴费 编辑:程序博客网 时间:2024/06/06 19:53

我用的是spring4.3.11的jar包

1.配置文件的实现方式

代码写在aop包上

主业务接口,IMainBiz

package aop;public interface IMainBiz {public void doMainBiz();}

主业务实现类,MainBiz

package aop;public class MainBiz  implements IMainBiz{public void doMainBiz(){System.out.println(1/0);System.out.println("核心业务");}}
切面业务,SubBiz

package aop;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;public class SubBiz {public void doSubBiz(JoinPoint joinPoint){//目标对象类信息System.out.println(joinPoint.getTarget().getClass().getSimpleName());System.out.println(joinPoint.getArgs());//切入点,主业务方法System.out.println(joinPoint.getSignature());System.out.println("切面业务");try {((ProceedingJoinPoint) joinPoint).proceed();} catch (Throwable e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println("横切业务2");}public void doSubBiz2(Exception ex){if(ex instanceof ArithmeticException){System.out.println("数字异常");}else{System.out.println("未知异常");}}}
测试类Main

package aop;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {public static void main(String[] args) {ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml");//cglib产生的代理对象,继承了mainbiz,经行子类扩展的功能//一定要接口接受IMainBiz mainBiz= (IMainBiz) applicationContext.getBean("mainbiz");mainBiz.doMainBiz();}}
配置文件:applicationContext.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.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"><!--目标对象 --><bean id="mainbiz" class="aop.MainBiz"></bean><!--切面 --><bean id="subbiz" class="aop.SubBiz"></bean><aop:config><!--切入点 --><aop:pointcut expression="execution(public void aop.MainBiz.doMainBiz())"id="pointcut" /><!--引入切面 --><aop:aspect ref="subbiz"><!--切入策略 --><!-- <aop:around method="doSubBiz" pointcut-ref="pointcut" /> --><aop:after-throwing method="doSubBiz2" pointcut-ref="pointcut" throwing="ex"/></aop:aspect></aop:config></beans>

2.实现通知接口并配合配置文件的方式

代码在advisor包上

主业务接口

package advisor;public interface IMainBiz {public void doMainBiz();}
主业务实现类

package advisor;public class MainBiz  implements IMainBiz{public void doMainBiz(){System.out.println("核心业务");}}
切面业务类,实现了接口

使用了advisor配置增强处理,

MethodBeforAdvice前置通知

AfterReturningAdvice后置通知,这个后置通知可以接受返回值,但是别的那几种方法是不能接收返回值

MethodInterceptor环绕通知

ThrowsAdvice异常通知,较为特殊,没有接口方法所以要手动在实现类中加入

public void afterThrowing(Method method,Object[] args,Object target,Exception ex){}

package advisor;import java.lang.reflect.Method;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.springframework.aop.MethodBeforeAdvice;//使用了Advisor配置增强处理
public class SubBiz implements MethodBeforeAdvice{@Overridepublic void before(Method method, Object[] args, Object obj) throws Throwable {// TODO Auto-generated method stubSystem.out.println("切面方法");}}
测试类Main

package advisor;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {public static void main(String[] args) {ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext2.xml");IMainBiz iMainBiz = (IMainBiz) applicationContext.getBean("mainbiz");iMainBiz.doMainBiz();}}

配置文件applicationContext2.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.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"><bean id="mainbiz" class="adcisor.MainBiz"></bean><bean id="subbiz" class="adcisor.SubBiz"></bean><!--Aop配置  --><aop:config><aop:pointcut expression="execution(public void advisor.MainBiz.doMainBiz())" id="pointcut" /><!--切入策略  --><aop:advisor advice-ref="subbiz" pointcut-ref="pointcut" /></aop:config></beans>

3.注解方式(个人觉得最简单的)

主业务接口ArithmeticCalculator

package test1;public interface ArithmeticCalculator {int add(int a,int b);int sub(int a,int b);int multiply(int a,int b);int divide(int a,int b);}
主业务实现类

package test1;import org.springframework.stereotype.Component;@Component("arithmeticCalculator")public class ArithmeticCalculatorImpl implements ArithmeticCalculator {@Overridepublic int add(int a, int b) {int result = a + b;return result;}@Overridepublic int sub(int a, int b) {int result = a - b;return result;}@Overridepublic int multiply(int a, int b) {int result = a * b;return result;}@Overridepublic int divide(int a, int b) {int result = a / b;return result;}}
切面业务类

package test1;import java.util.Arrays;import java.util.List;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.springframework.stereotype.Component;//可以使用@order()来设置优先级,数字越小,优先级越高@Aspect@Componentpublic class LogginAspect {@Before("execution(public int test1.ArithmeticCalculatorImpl.*(int , int))")public void beforMethod(JoinPoint joinPoint){String name = joinPoint.getSignature().getName();Object[] args = joinPoint.getArgs();List<Object> list = Arrays.asList(args);System.out.println("前置通知:"+name+" args "+list);}@After("execution(public int test1.ArithmeticCalculatorImpl.*(int , int))")public void afterMethod(JoinPoint joinPoint){String name = joinPoint.getSignature().getName();Object[] args = joinPoint.getArgs();List<Object> list = Arrays.asList(args);System.out.println("后置通知:"+name+" args "+list);}@AfterReturning(value="execution(public int test1.ArithmeticCalculatorImpl.*(int , int))",returning="result")public void returnMethod(JoinPoint joinPoint,Object result){String name = joinPoint.getSignature().getName();Object[] args = joinPoint.getArgs();List<Object> list = Arrays.asList(args);System.out.println("返回通知:"+name+" args "+list+" result "+result);}@AfterThrowing(value="execution(public int test1.ArithmeticCalculatorImpl.*(int , int))",throwing="ex")public void throwMethod(JoinPoint joinPoint,Exception ex){String name = joinPoint.getSignature().getName();Object[] args = joinPoint.getArgs();List<Object> list = Arrays.asList(args);System.out.println("异常通知:"+name+" args "+list+" result "+ex);}@Around("execution(public int test1.ArithmeticCalculatorImpl.*(int , int))")public Object around(ProceedingJoinPoint pjd){String methodname=pjd.getSignature().getName();Object proceed =null;//执行目标方法try {//前置通知System.out.println("the method :"+methodname+"  begins with" +Arrays.asList(pjd.getArgs()));proceed=pjd.proceed();//返回通知System.out.println("the method return  with "+ proceed);} catch (Throwable e) {// TODO Auto-generated catch blockSystem.out.println("the method pccurs exception "+e);}//后置通知System.out.println("the method end ");return proceed;}

测试类Main

package test1;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.sun.media.sound.AiffFileReader;public class Main {public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext3.xml");ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) applicationContext.getBean("arithmeticCalculator");arithmeticCalculator.divide(3, 1);//System.out.println(add);}}
配置文件applicationContext3.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.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"><!--开启扫描包  --><context:component-scan base-package="test1" /><!-- 开启aop注解驱动 --><aop:aspectj-autoproxy></aop:aspectj-autoproxy></beans>
在切面类加入支持的注解:
@before
@after 
@afterThrowing
@afterReturning
@aroud
@aspect
@pointcut
4.通过实现接口方式

主业务接口IMainBiz

package aop2;public interface IMainBiz {public void doMainBiz();}

主业务实现类MainBiz

package aop2;public class MainBiz  implements IMainBiz{public void doMainBiz(){System.out.println("核心业务");}}
切面类SubBiz

package aop2;import java.lang.reflect.Method;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.springframework.aop.MethodBeforeAdvice;public class SubBiz implements MethodBeforeAdvice {public void doSubBiz() {System.out.println("切面方法");}@Overridepublic void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {doSubBiz();}}
测试类Main

package aop2;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {public static void main(String[] args) {ApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext4.xml");//这里getBean得到的不算主业务的id,而是ProxyFactoryBean的idIMainBiz  imMainBiz= (IMainBiz) applicationContext.getBean("myproxy");imMainBiz.doMainBiz();}}

配置文件applicationContext4.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.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd"><!-- 目标类--><bean id="mainbiz" class="aop2.MainBiz"></bean><!--切面类:实现通知接口--><bean id="subbiz" class="aop2.SubBiz"></bean><!-- 使用spring提供工厂类ProxyFactoryBean --><bean id="myproxy"  class="org.springframework.aop.framework.ProxyFactoryBean"><property name="proxyInterfaces"><list><value>aop2.IMainBiz</value></list></property><!-- 目标类信息 --><property name="targetName" value="mainbiz"></property><!-- 切面类信息 --><property name="interceptorNames"><list><value>subbiz</value></list></property></bean></beans>
创建ProxyFactoryBean代理对象

<bean id="myproxy"  class="org.springframework.aop.framework.ProxyFactoryBean">//指定的目标类实现的接口<property name="proxyInterfaces"><list><value>接口的完全限定名</value></list></property><!-- 目标类信息 --><property name="targetName" value="目标类ID"></property><!-- 切面类信息 --><property name="interceptorNames"><list><value>切面类的ID</value></list></property></bean>



原创粉丝点击