基于代理的spring aop中,切面的实现

版权声明:仅供学习交流使用 https://blog.csdn.net/drxRose/article/details/84867195

基于代理的spring aop中,使用接口Advisor表示切面.

  • 对目标对象织入通知可使用PointAdvisor接口及其子类,定义切面.其子类中有便捷的DefaultPointcutAdvisor实现类可使用.
  • 对目标对象织入引入功能时,可使用IntroductionAdvisor接口.
  • 切面即切点和通知的组合,可使用DefaultPointcutAdvisor来定义切点和通知.

  1. org.springframework.aop.Pointcut的结构
  2. org.aopalliance.aop.Advice的结构

关于PointCut的实现,又需要有ClassFilter和MethodMatcher来匹配目标对象类型和目标对象的方法.


目标对象类

package siye;
public class TargetObj_reuse
{
	public void work()
	{
		System.out.println("work....");
	}
	public void wake(int num)
	{
		System.out.println("user_wake..." + num);
	}
}

对目标对象引入新特性的接口

package siye;
public interface NewFeature
{
	void eat();
}

前置通知实现类

package siye;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class BeforeAdviceImpl implements MethodBeforeAdvice
{
	@Override
	public void before(Method method, Object[] args,
			Object target) throws Throwable
	{
		System.out.println("方法即将被调用.");
	}
}

引入实现类

package siye;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
public class IntroductionAdviceImpl extends
		DelegatingIntroductionInterceptor implements
		NewFeature
{
	private static final long serialVersionUID =
			-543070161703560988L;
	@Override
	public Object invoke(MethodInvocation mi)
			throws Throwable
	{
		return super.invoke(mi);
	}
	@Override
	public void eat()
	{
		System.out.println("eat...");
	}
}

目标对象类型匹配简单实现类

package siye;
import org.springframework.aop.ClassFilter;
public class GenericClassFilterImpl implements ClassFilter
{
	@Override
	public boolean matches(Class<?> clazz)
	{
		if (TargetObj_reuse.class.isAssignableFrom(clazz))
		{// 在此,可配置要切入的对象类型的集合.
			return true;
		}
		return false;
	}
}

切点实现类,包含多种情况切点是切点实现的非共有类

package siye;
import java.lang.reflect.Method;
import java.util.regex.Pattern;
import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.support.DynamicMethodMatcher;
import org.springframework.aop.support.StaticMethodMatcher;
/**
 * 标记接口
 */
public interface AllPointcut
{
}
/**
 * 定义静态方法切点
 * 类说明:
 * MyStaticPointcutImpl,实现切点.
 * StaticMethodMatcherImpl,实现方法匹配.
 */
class MyStaticPointcutImpl implements Pointcut
{// 定义方法和类型匹配
	@Override
	public ClassFilter getClassFilter()
	{
		return new GenericClassFilterImpl();
	}
	@Override
	public MethodMatcher getMethodMatcher()
	{
		return new StaticMethodMatcherImpl();
	}
}
class StaticMethodMatcherImpl extends StaticMethodMatcher
{// 定义静态方法匹配
	@Override
	public boolean matches(Method method,
			Class<?> targetClass)
	{
		if ("work".equals(method.getName()))
		{
			return true;
		}
		return false;
	}
}
/**
 * 定义动态方法切点.
 * 接口DynamicMethodMatcher.
 * Convenient abstract superclass for dynamic method matchers,
 * which do care about arguments at runtime.
 * 
 * MyDynamicPointcutImpl,实现切点.
 * DynamicMethodMatcherImpl,实现方法匹配.
 */
class MyDynamicPointcutImpl implements Pointcut
{// 定义方法和类型匹配
	@Override
	public ClassFilter getClassFilter()
	{
		return new GenericClassFilterImpl();
	}
	@Override
	public MethodMatcher getMethodMatcher()
	{
		return new DynamicMethodMatcherImpl();
	}
}
class DynamicMethodMatcherImpl extends DynamicMethodMatcher
{
	@Override
	public boolean matches(Method method,
			Class<?> targetClass, Object... args)
	{
		if (Pattern.matches("^w\\w+$", method.getName())
				&& args.length > 0)
		{// 匹配以开头且有参数的方法
			// System.out.println(targetClass);
			return true;
		}
		return false;
	}
}

测试类

package siye;
import org.aopalliance.aop.Advice;
import org.junit.Before;
import org.junit.Test;
import org.springframework.aop.Advisor;
import org.springframework.aop.Pointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.DefaultIntroductionAdvisor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
public class UnitTest
{
	TargetObj_reuse targetObj;// 声明目标对象
	Advice adviceImpl;// 声明通知实现
	DefaultPointcutAdvisor advisor;// 声明切面
	ProxyFactory proxyFactory; // 声明代理工厂
	Pointcut pointcutImpl; // 声明切点
	@Before
	public void prepare()
	{
		// 实例化目标对象
		targetObj = new TargetObj_reuse();
		// 实例化前置通知
		adviceImpl = new BeforeAdviceImpl();
		// 实例化通用的切面
		advisor = new DefaultPointcutAdvisor();
		// 实例化代理工厂
		proxyFactory = new ProxyFactory();
		// 设置目标代理
		proxyFactory.setTarget(targetObj);
		// 强制使用cglib代理
		proxyFactory.setProxyTargetClass(true);
	}
	@Test
	public void testStaticAspect()
	{
		pointcutImpl = new MyStaticPointcutImpl();
		advisor.setPointcut(pointcutImpl);// 设置切面的切点
		advisor.setAdvice(adviceImpl); // 设置切面的通知
		proxyFactory.addAdvisor(advisor);
		TargetObj_reuse obj =
				(TargetObj_reuse) proxyFactory.getProxy();
		obj.work();// 前置通知对此类的此方法生效
	}
	@Test
	public void testDynamicAspect()
	{
		pointcutImpl = new MyDynamicPointcutImpl();
		// 设置切面的切点
		advisor.setPointcut(pointcutImpl);
		// 设置切面的通知
		advisor.setAdvice(adviceImpl);
		proxyFactory.addAdvisor(advisor);
		TargetObj_reuse obj =
				(TargetObj_reuse) proxyFactory.getProxy();
		obj.work();
		obj.wake(12);
	}
	@Test
	public void testIntroductionAspect()
	{
		// 因引入,要使用此通知器.
		Advice advice = new IntroductionAdviceImpl();
		Advisor advisor =
				new DefaultIntroductionAdvisor(advice);
		proxyFactory.addAdvisor(advisor);
		TargetObj_reuse obj0 =
				(TargetObj_reuse) proxyFactory.getProxy();
		obj0.work();
		NewFeature obj1 = (NewFeature) obj0;
		obj1.eat();
	}
}


  • 基于xml的实现,可借用ProxyFactoryBean来实现,具体的实现区别是设置其属性.
  • 可直接实现Advisor接口下的特定通知器,来完成自定义的切面(方法与上类似).
  • 也可直接实现Pointcut接口下的特定通知器,来完成自定义的切面(方法与上类似).
  • 以上的代码实例,是以实现MethodMatcher接口下的特定接口或类来实现的.
Advisor接口下的特定切面 Pointcut接口下的特定切点 MethodMatcher接口下的匹配方法
DefaultIntroductionAdvisor StaticMethodMatcherPointcut ControlFlowPointcut
DefaultPointcutAdvisor DynamicMethodMatcher DynamicMethodMatcher
NameMatchMethodPointcutAdvisor AnnotationMethodMatcher StaticMethodMatcher
RegexpMethodPointcutAdvisor ExpressionPointcut TrueMethodMatcher
StaticMethodMatcherPointcutAdvisor ControlFlowPointcut IntroductionAwareMethodMatcher
e.g. ComposablePointcut e.g.
  e.g.  

猜你喜欢

转载自blog.csdn.net/drxRose/article/details/84867195
今日推荐