长春市长春网站建设可以做直播卖产品的网站
news/
2025/10/6 23:36:11/
文章来源:
长春市长春网站建设,可以做直播卖产品的网站,长春seo网站管理,学视频剪辑报个班的多少钱当需要在方法前后做一些操作就需要借助动态代理来实现
一、动态代理实现方法
1、jdk自带实现方式
jdk实现代理是被代理类实现接口的方式
public interface UserInterface {void test();
}public class UserService implements UserInterface {public void test() {System.o…当需要在方法前后做一些操作就需要借助动态代理来实现
一、动态代理实现方法
1、jdk自带实现方式
jdk实现代理是被代理类实现接口的方式
public interface UserInterface {void test();
}public class UserService implements UserInterface {public void test() {System.out.println(call test method);}}UserService target new UserService();Object o Proxy.newProxyInstance(Test.class.getClassLoader(), new Class[]{UserInterface.class}, new InvocationHandler() {Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(test method before);Object invoke method.invoke(target, args);System.out.println(test method after);return invoke;}});// 只能代理实现UserInterface接口的类不能强转成UserServiceUserInterface userInterface (UserInterface)o;userInterface.test();
打印结果
test method before call test method test method after 必须基于实现接口产生代理对象类型是UserInterface而不是UserService
2、基于cglib实现
相比jdk动态代理cglib不需要修改代码就可以实现动态代理cglib实现代理是继承被代理类的方式
public class UserService {public void test() {System.out.println(call test method);}public void a() {System.out.println(call test a);}
}UserService target new UserService();// 通过cglib技术Enhancer enhancer new Enhancer();enhancer.setSuperclass(UserService.class);// 定义额外逻辑也就是代理逻辑enhancer.setCallbacks(new Callback[]{new MethodInterceptor() {Overridepublic Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {System.out.println(before...);Object result methodProxy.invoke(target, objects);System.out.println(after...);return result;}}, NoOp.INSTANCE});enhancer.setCallbackFilter(new CallbackFilter() {Overridepublic int accept(Method method) {if (method.getName().equals(test)) {return 0;} else {return 1;}}});// 动态代理所创建出来的UserService对象UserService userService (UserService) enhancer.create();// 执行这个userService的test方法时就会额外会执行一些其他逻辑userService.test();// 调用a方法时对应过滤返回的是1NoOp.INSTANCE是空操作不会对代理对象做任何操作userService.a();
打印结果
before... call test method after... call test a
3、spring对jdk和cglib进行封装的ProxyFactory
public class UserService {public void test() {System.out.println(call test method);}
}UserService target new UserService();ProxyFactory proxyFactory new ProxyFactory();proxyFactory.setTarget(target);
// proxyFactory.setInterfaces(UserInterface.class); // jdk动态时设置proxyFactory.addAdvice(new MethodInterceptor() {Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {System.out.println(before...);Object result invocation.proceed();System.out.println(after...);return result;}});UserService userService (UserService) proxyFactory.getProxy();userService.test();
打印结果
before... call test method after...
4、Advice分类
Before Advice方法之前执行After returning advice方法return后执行After throwing advice方法抛异常后执行After (finally) advice方法执行完finally之后执行这是最后的比return更后Around advice这是功能最强大的Advice可以自定义执行顺序
Before Advice
ProxyFactory proxyFactory new ProxyFactory();proxyFactory.setTarget(target);
// proxyFactory.setInterfaces(UserInterface.class); // jdk动态时设置proxyFactory.addAdvice(new TestBeforeAdvice());UserService userService (UserService) proxyFactory.getProxy();userService.test();public class TestBeforeAdvice implements MethodBeforeAdvice {Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {System.out.println(方法执行之前);}
}public class UserService {public void test() {System.out.println(call test method);}
}
打印结果
方法执行之前 call test method
After returning advice
ProxyFactory proxyFactory new ProxyFactory();proxyFactory.setTarget(target);
// proxyFactory.setInterfaces(UserInterface.class); // jdk动态时设置proxyFactory.addAdvice(new TestAfterReturningAdvice());UserService userService (UserService) proxyFactory.getProxy();userService.test();public class TestAfterReturningAdvice implements AfterReturningAdvice {Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {System.out.println(方法返回之后);}
}public class UserService {public void test() {System.out.println(call test method);}
}
打印结果
call test method 方法返回之后
After throwing advice
可根据异常类型在指定异常发生时做对应操作
ProxyFactory proxyFactory new ProxyFactory();proxyFactory.setTarget(target);
// proxyFactory.setInterfaces(UserInterface.class); // jdk动态时设置proxyFactory.addAdvice(new TestAfterThrowingAdvice());UserService userService (UserService) proxyFactory.getProxy();userService.test();public class TestAfterThrowingAdvice implements ThrowsAdvice {public void afterThrowing(Method method, Object[] args, Object target, Exception ex) {System.out.println(方法执行发生异常);}
}public class UserService {public void test() {System.out.println(call test method);throw new RuntimeException();}
}
打印结果
call test method
方法执行发生异常
Exception in thread main java.lang.RuntimeExceptionat com.zhouyu.service.UserService.test(UserService.java:25)at com.zhouyu.service.UserService$$FastClassBySpringCGLIB$$7bfcfe0.invoke(generated)at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:791)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:166)at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)at org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor.invoke(ThrowsAdviceInterceptor.java:113)at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:198)at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:762)at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:704)at com.zhouyu.service.UserService$$EnhancerBySpringCGLIB$$e9a0fc71.test(generated)at com.zhouyu.Test.main(Test.java:25)
Around advice
UserService target new UserService();ProxyFactory proxyFactory new ProxyFactory();proxyFactory.setTarget(target);
// proxyFactory.setInterfaces(UserInterface.class); // jdk动态时设置proxyFactory.addAdvice(new TestAroundAdvice());UserService userService (UserService) proxyFactory.getProxy();userService.test();public class UserService {public void test() {System.out.println(call test method);}
}public class TestAroundAdvice implements MethodInterceptor {NullableOverridepublic Object invoke(NotNull MethodInvocation invocation) throws Throwable {System.out.println(方法执行之前);Object proceed invocation.proceed();System.out.println(方法执行之后);return proceed;}
}
打印结果
方法执行之前 call test method 方法执行之后
上述的Advice只要是UserService类的方法都会被代理执行
5、Advisor
添加自己想执行的执行的方法下面代码只会执行test方法的Advice代码
public class UserService {public void test() {System.out.println(call test method);}public void a() {System.out.println(call test a);}
}UserService target new UserService();ProxyFactory proxyFactory new ProxyFactory();proxyFactory.setTarget(target);
// proxyFactory.setInterfaces(UserInterface.class); // jdk动态时设置
// proxyFactory.addAdvice(new TestBeforeAdvice());proxyFactory.addAdvisor(new PointcutAdvisor() {Overridepublic Pointcut getPointcut() {return new StaticMethodMatcherPointcut() {Overridepublic boolean matches(Method method, Class? targetClass) {if (method.getName().equals(test)) {return true;}return false;}};}Overridepublic Advice getAdvice() {return new TestBeforeAdvice();}Overridepublic boolean isPerInstance() {return false;}});UserService userService (UserService) proxyFactory.getProxy();userService.test();userService.a();
打印结果
方法执行之前 call test method call test a
二、ProxyFactoryBean
利用ProxyFactoryBean生成一个代理对象执行test方法之前执行代理逻辑
public class UserService {public void test() {System.out.println(call test method);}public void a() {System.out.println(call test a);}
}Beanpublic ProxyFactoryBean userServiceProxy() {ProxyFactoryBean proxyFactoryBean new ProxyFactoryBean();proxyFactoryBean.setTarget(new UserService());proxyFactoryBean.addAdvice(new TestBeforeAdvice());return proxyFactoryBean;}AnnotationConfigApplicationContext applicationContext new AnnotationConfigApplicationContext(AppConfig.class);UserService userService (UserService) applicationContext.getBean(userServiceProxy);userService.test();
打印结果
方法执行之前 call test method
三、BeanNameAutoProxyCreator
beanName匹配到的将会自动创建代理对象根据设置的Advice在调用方法时执行相关代理逻辑通过beanPostProcessor把Advice添加到一个集合中当调用调用被代理类时指定的beanName的方法执行时都会执行代理逻辑
Beanpublic BeanNameAutoProxyCreator beanNameAutoProxyCreator() {BeanNameAutoProxyCreator beanNameAutoProxyCreator new BeanNameAutoProxyCreator();beanNameAutoProxyCreator.setBeanNames(userSe*);beanNameAutoProxyCreator.setInterceptorNames(testBeforeAdvice);beanNameAutoProxyCreator.setProxyTargetClass(true);return beanNameAutoProxyCreator;}Component
public class TestBeforeAdvice implements MethodBeforeAdvice {Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {System.out.println(方法执行之前);}
}AnnotationConfigApplicationContext applicationContext new AnnotationConfigApplicationContext(AppConfig.class);UserService userService (UserService) applicationContext.getBean(userService);userService.test();
打印结果
方法执行之前 call test method
四、DefaultAdvisorAutoProxyCreator
// 定义一个advisorBeanpublic DefaultPointcutAdvisor defaultPointcutAdvisor(){NameMatchMethodPointcut pointcut new NameMatchMethodPointcut();pointcut.addMethodName(test);DefaultPointcutAdvisor defaultPointcutAdvisor new DefaultPointcutAdvisor();defaultPointcutAdvisor.setPointcut(pointcut);defaultPointcutAdvisor.setAdvice(new TestBeforeAdvice());return defaultPointcutAdvisor;}// 执行beanPostProcessor时会把advisor添加到一个集合中Beanpublic DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator new DefaultAdvisorAutoProxyCreator();return defaultAdvisorAutoProxyCreator;}AnnotationConfigApplicationContext applicationContext new AnnotationConfigApplicationContext(AppConfig.class);UserService userService (UserService) applicationContext.getBean(userService);userService.test();
打印结果
方法执行之前 call test method
五、AOP概念
AspectJ是在编译时对字节码进行了修改是直接在UserService类对应的字节码中进行增强的也就是可以理解为是在编译时就会去解析Before这些注解然后得到代理逻辑加入到被代理的类中的字节码中去的所以如果想用AspectJ技术来生成代理对象 是需要用单独的AspectJ编译器的。我们在项目中很少这么用我们仅仅只是用了Before这些注解而我们在启动Spring的过程中Spring会去解析这些注解然后利用动态代理机制生成代理对象的。
Aspect表示切面比如被Aspect注解的类就是切面可以在切面中去定义Pointcut、Advice等等Join point表示连接点表示一个程序在执行过程中的一个点比如一个方法的执行比如一个异常的处理在Spring AOP中一个连接点通常表示一个方法的执行。Advice表示通知表示在一个特定连接点上所采取的动作。Advice分为不同的类型后面详细讨论在很多AOP框架中包括Spring会用Interceptor拦截器来实现Advice并且在连接点周围维护一个Interceptor链Pointcut表示切点用来匹配一个或多个连接点Advice与切点表达式是关联在一起的Advice将会执行在和切点表达式所匹配的连接点上Introduction可以使用DeclareParents来给所匹配的类添加一个接口并指定一个默认实现Target object目标对象被代理对象AOP proxy表示代理工厂用来创建代理对象的在Spring Framework中要么是JDK动态代理要么是CGLIB代理Weaving表示织入表示创建代理对象的动作这个动作可以发生在编译时期比如Aspejctj或者运行时比如Spring AOP
AspectJ定义的几个注解
BeforeAfterReturningAfterThrowingAfterAround
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/929820.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!