主页 > 游戏开发  > 

spring中aop

spring中aop
jdk动态代理

Proxy.newProxyInstance(类加载器,所有的接口,代理方法InvocationHandler )

public static void main(String[] args) { CalculatorImpl calculator = new CalculatorImpl(); // 生成一个代理对象 /** * 1.类加载器 * 2. 要生成的代理对象他需要实现的接口 * 3. InvocationHandle : 动态代理的方法 * * 方法返回: 代理对象 这个对象需要实现的接、 */ Calculator proxObj = (Calculator) Proxy.newProxyInstance(Main.class.getClassLoader(), new Class[]{Calculator.class}, new InvocationHandler() { /** * * @param proxy 生成的代理对象 * * @param method 被代理的方法 * * @param args 方法的参数 * * @return 代理方法的返回值 * @throws Throwable */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { long startTime = System.currentTimeMillis(); Object invoke = method.invoke(calculator, args); long endTime = System.currentTimeMillis(); System.out.println(method.getName() + "方法执行时间" + (endTime - startTime)); return invoke; } }); proxObj.add(1, 2); }

jdk动态代理,必须要有接口

cglib动态代理

cglib本质是写一个拦截器,把当前对象的方法拦截下来,进行增强,,返回一个当前对象的子类

<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>

实现MethodInterceptor接口,创建一个拦截器:

package com.cj; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy; import java.lang.reflect.Method; /** * @author cc * @date 2025-02-20 09:25 **/ public class MyMethodInterceptor implements MethodInterceptor { /** * 方法的拦截器,,,,将目标方法拦截下来,, 拦截下来增强功能 * @param obj 代理的对象 * @param method 代理的方法 * @param args 代理的方法参数 * @param methodProxy 被代理的方法 * @return 代理方法的返回值 * @throws Throwable */ @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { long startTime = System.currentTimeMillis(); // 生成一个继承他的类 ,,, 调用父类的方法 Object result = methodProxy.invokeSuper(obj, args); long endTime = System.currentTimeMillis(); System.out.println("diff:"+(endTime-startTime)); return result; } } public static void main(String[] args) { Enhancer enhancer = new Enhancer(); // 设置父类 ==》 根据父类生成子类 enhancer.setSuperclass(UserService.class); // 设置拦截器 enhancer.setCallback(new MyMethodInterceptor()); // 创建代理对象 UserService o = (UserService) enhancer.create(); o.sayHello(); }

生成了一个代理对象的子类,,

jdk动态代理只能代理有接口的类,,,cglib都能代理,,

spring中动态代理 <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>6.1.14</version> </dependency>

ProxyFactory

public static void main(String[] args) { // spring中的动态代理使用的对象 ProxyFactory proxyFactory = new ProxyFactory(); // 设置被代理的对象 proxyFactory.setTarget(new CalculatorImpl()); proxyFactory.setInterfaces(Calculator.class); // 设置为true,,,表示使用cglib动态代理 // 为false就会根据情况(是否有接口)自动选择 proxyFactory.setProxyTargetClass(true); // 被代理方法上额外的增强逻辑 proxyFactory.addAdvice(new MethodInterceptor() { @Override public Object invoke(MethodInvocation invocation) throws Throwable { Method method = invocation.getMethod(); long startTime = System.currentTimeMillis(); // 执行方法 Object proceed = invocation.proceed(); long endTime = System.currentTimeMillis(); System.out.println("diff:"+(endTime-startTime)); return proceed; } }); CalculatorImpl proxy = (CalculatorImpl) proxyFactory.getProxy(); proxy.add(1, 2); } spring中aop

通知:

前置通知 : 方法执行前调用后置通知返回通知 : 获取到方法返回值的时候调用异常通知: 抛出错误的时候调用环绕通知: 集大成者

写一个切面:

package com.cj; import org.aopalliance.intercept.Joinpoint; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; /** * 1.前置通知 : * 后置通知 * 返回通知 : 拿到返回值的之后会触发,,, void也算是返回值 * 异常通知: 抛出异常的时候触发 * 环绕通知: 集大成者 * * @author cc * @date 2025-02-20 10:38 **/ public class LogAdvice { public void before(JoinPoint jp){ // 目标方法的名字 String name = jp.getSignature().getName(); System.out.println(name+"方法开始执行了"); } public void after(JoinPoint jp){ // 目标方法的名字 String name = jp.getSignature().getName(); System.out.println(name+"方法执行结束了"); } /** * * @param jp * @param val 目标方法的返回值 : 和目标方法的返回值类型一致 */ public void afterReturning(JoinPoint jp,Void val){ // 目标方法的名字 String name = jp.getSignature().getName(); System.out.println(name+"方法afterReturning "+val); } public void afterThrowing(JoinPoint jp,Throwable e){ String name = jp.getSignature().getName(); System.out.println(name+"after throwing"+e.getMessage()); } public Object around(ProceedingJoinPoint pjp){ String name = pjp.getSignature().getName(); Object proceed = null; try { System.out.println(name+"method start"); proceed = pjp.proceed(); System.out.println(name+"method end"); } catch (Throwable e) { // 异常通知 System.out.println("exception"); throw new RuntimeException(e); } return proceed; } }

xml配置:

<bean class="com.cj.CalculatorImpl" id="calculatorImpl"/> <bean class="com.cj.LogAdvice" id="logAdvice" /> <!-- 配置aop--> <aop:config> <aop:pointcut id="pc1" expression="execution(* com.cj.CalculatorImpl.*(..))"/> <!-- 配置切面: 把切面的bean写进去--> <aop:aspect ref="logAdvice"> <aop:before method="before" pointcut-ref="pc1" /> <aop:after method="after" pointcut-ref="pc1" /> <!-- 返回的值,,, 参数一个是jp,一个是val--> <aop:after-returning method="afterReturning" pointcut-ref="pc1" returning="val"/> <aop:after-throwing method="afterThrowing" pointcut-ref="pc1" throwing="e"/> <aop:around method="around" pointcut-ref="pc1"/> </aop:aspect> </aop:config> public static void main(String[] args) { ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("beans.xml"); Calculator bean = ctx.getBean(Calculator.class); System.out.println("bean = " + bean); bean.add(1,2); bean.sub(2,1); }

<bean class="com.cj.CalculatorImpl" id="calculatorImpl"/> 这个实现类已经被代理了,已经取不到这个实现类的实例了,, 只能按照接口去找实现类,,, <aop:config proxy-target-class="true"> : proxy-target-class为true表示使用cglib

java配置类使用aop @Component @Aspect // 标记这个类是一个切面 @EnableAspectJAutoProxy // 开启自动代理 public class LogAdvisor { @Pointcut("execution(* com.cj.CalculatorImpl.*(..))") public void pc1(){} @Before("pc1()") public void before(JoinPoint jp){ // 目标方法的名字 String name = jp.getSignature().getName(); System.out.println(name+"方法开始执行了"); } @After("pc1()") public void after(JoinPoint jp){ // 目标方法的名字 String name = jp.getSignature().getName(); System.out.println(name+"方法执行结束了"); } /** * * @param jp * @param val 目标方法的返回值 : 和目标方法的返回值类型一致 */ @AfterReturning(value = "pc1()",returning = "val") public void afterReturning(JoinPoint jp,Void val){ // 目标方法的名字 String name = jp.getSignature().getName(); System.out.println(name+"方法afterReturning "+val); } @AfterThrowing(value = "pc1()",throwing = "e") public void afterThrowing(JoinPoint jp,Throwable e){ String name = jp.getSignature().getName(); System.out.println(name+"after throwing"+e.getMessage()); } @Around("pc1()") public Object around(ProceedingJoinPoint pjp){ String name = pjp.getSignature().getName(); Object proceed = null; try { System.out.println(name+"method start"); proceed = pjp.proceed(); System.out.println(name+"method end"); } catch (Throwable e) { // 异常通知 System.out.println("exception"); throw new RuntimeException(e); } return proceed; } }

@EnableAspectJAutoProxy(proxyTargetClass = true) // 开启自动代理 proxyTargetClass=true 表示使用cglib动态代理

标签:

spring中aop由讯客互联游戏开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“spring中aop