关于动态代理的学习总结

package com;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

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.aspectj.lang.annotation.Pointcut;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import com.service.TestService;
import com.service.impl.TestServiceImpl;


//当所代理对象有实现接口时
public class JDKProxy implements InvocationHandler {
private Object targetObject;

public Object createProxyInstance(Object targetObject) {
this.targetObject = targetObject;
Object result = null;
result = Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(),
this.targetObject.getClass().getInterfaces(), this);
return result;
}

public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
TestServiceImpl bean = (TestServiceImpl) this.targetObject;
Object result = null;
if(bean.getTestDao() != null) {
//before advice()...前置通知
try {
result = method.invoke(this.targetObject, args);
//after advice()...后置通知
} catch (Exception e) {
//exception advice()...例外通知
} finally {
//finally advice()...最终通知
}
}
return result;
}
}


//当对应的TestSerice2没有实现接口的时候,可以使用CGlib来动态代理
class CGlibProxy implements MethodInterceptor {
private Object targetObject;

public Object createProxyInstance(Object targetObject) {
this.targetObject = targetObject;
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(this.targetObject.getClass());
enhancer.setCallback(this);
return enhancer.create();
}

public Object intercept(Object proxy, Method method, Object[] args,
MethodProxy methodProxy) throws Throwable {
TestService bean = (TestService) this.targetObject;
Object result = null;
if(bean != null) {
result = methodProxy.invoke(this.targetObject, args);
}
return result;
}
}


//切面
@Aspect
class MyInterceptor {
@Pointcut("execution (* com.service.impl.*.*(..))")
private void anyMethod() {}  //声明一个切入点

@Before("anyMethod() && args(name)")
public void add(String message) {
//只对满足anyMethod切入点的所有方法和只有一个参数的方法插入切入点
System.out.println(message + "前置通知");
}

@AfterReturning(pointcut="anyMethod()", returning="otherMess")
public void afterAdd(String otherMess) {
//只对返回值为String类型的方法插入切面并且返回的值作为切入方法的参数传入
System.out.println(otherMess + "后置通知");
}

@After("anyMethod() && args(name)")
public void finallyAdd(String finalMess) {
System.out.println(finalMess + "最终通知");
}

@AfterThrowing("anyMethod() && args(name)")
public void exceptionAdd(String exceptionMess) {
System.out.println(exceptionMess + "例外通知");
}

@Around("anyMethod()")
public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint)
throws Throwable {
Object result = null;
if (result == null) { //判断用户是否存在权限
System.out.println("into 环绕通知");
result = proceedingJoinPoint.proceed();
System.out.println("out 环绕通知");
}
return result;
}
}


//切面2  采用XMl的配置方式配置切面
class MyInterceptor2 {
private void anyMethod() {}  //声明一个切入点

public void add(String message) {
//只对满足anyMethod切入点的所有方法和只有一个参数的方法插入切入点
System.out.println(message + "前置通知");
}

public void afterAdd(String otherMess) {
//只对返回值为String类型的方法插入切面并且返回的值作为切入方法的参数传入
System.out.println(otherMess + "后置通知");
}

public void finallyAdd(String finalMess) {
System.out.println(finalMess + "最终通知");
}

public void exceptionAdd(String exceptionMess) {
System.out.println(exceptionMess + "例外通知");
}

public Object aroundMethod(ProceedingJoinPoint proceedingJoinPoint)
throws Throwable {
Object result = null;
if (result == null) { //判断用户是否存在权限
System.out.println("into 环绕通知");
result = proceedingJoinPoint.proceed();
System.out.println("out 环绕通知");
}
return result;
}
}

//spring-aop.xml的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"

xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
">
<!-- 基于XML配置方式声明切面 -->
<bean id="myInterceptor" class="com.MyInterceptor2"/>
<aop:config>
<aop:aspect id="myaop" ref="myInterceptor">
<!-- 声明一个切入点 -->
<aop:pointcut expression="execution(* com.service.impl.*(..))" id="myPointCut"/>
<!-- 前置通知 -->
<aop:before method="add" pointcut-ref="myPointCut"/>
<!-- 后置通知 -->
<aop:after-returning method="afterAdd" pointcut-ref="myPointCut"/>
<!-- 最终通知 -->
<aop:after method="finallyAdd" pointcut-ref="myPointCut"/>
<!-- 例外通知 -->
<aop:after-throwing method="exceptionAdd" pointcut-ref="myPointCut"/>
<!-- 环绕通知 -->
<aop:around method="aroundMethod" pointcut-ref="myPointCut"/>
</aop:aspect>
</aop:config>
</beans>

你可能感兴趣的:(java,spring,AOP)