我用的是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 block
e.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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://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{
@Override
public void before(Method method, Object[] args, Object obj) throws Throwable {
// TODO Auto-generated method stub
System.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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://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 {
@Override
public int add(int a, int b) {
int result = a + b;
return result;
}
@Override
public int sub(int a, int b) {
int result = a - b;
return result;
}
@Override
public int multiply(int a, int b) {
int result = a * b;
return result;
}
@Override
public 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
@Component
public 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 block
System.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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://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("切面方法");
}
@Override
public 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的id
IMainBiz 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.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://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>