海口商城网站建设,龙江外贸“半年报”,想做一个自己的网站怎么做,网站建设属于什么行业Spring-AOP
现象#xff1a;接口实现类中有两个#xff0c;doMethod1()调用了doMethod2(),此时对于AOP#xff0c;如果现在外部对象调用doMethod1()方法的时候#xff0c;会发现只有doMethod1()方法执行被拦截,AOP生效#xff0c;而doMethod1()内部调用doMethod2()时并没…Spring-AOP
现象接口实现类中有两个doMethod1()调用了doMethod2(),此时对于AOP如果现在外部对象调用doMethod1()方法的时候会发现只有doMethod1()方法执行被拦截,AOP生效而doMethod1()内部调用doMethod2()时并没有被拦截外部对象单独调用doMethod1()时会被拦截。
Service
public class JdkProxyDemoServiceImpl implements IJdkProxyService {Overridepublic void doMethod1() {doMethod2()System.out.println(JdkProxyServiceImpl.doMethod1());}Overridepublic String doMethod2() {System.out.println(JdkProxyServiceImpl.doMethod2());return hello world;}
}分析 拦截器的实现原理就是动态代理实现AOP机制。Spring的代理实现有两种一是基于 JDK Dynamic Proxy 技术而实现的二是基于 CGLIB 技术而实现的。如果目标对象实现了接口在默认情况下Spring会采用JDK的动态代理实现AOP
//JDK动态代理生成的JdkProxyDemoServiceImpl 的代理类
Service
public class JdkProxyDemoServiceProxy implements IJdkProxyService {private IJdkProxyService iJdkProxyService;public void setIJdkProxyService(IJdkProxyService iJdkProxyService) { this.iJdkProxyService iJdkProxyService; } public void doMethod1() {//前置通知doBefore() iJdkProxyService.doMethod1();}public String doMethod2() {//前置通知doBefore() return iJdkProxyService.doMethod2();}private void doBefore() { System.out.println( 前置通知...); }
}当使用时从IOC容器中获取的Bean对象都是代理对象而不是Bean对象本身由于this关键字应用的并不是该Bean对象的对象而是其本身因此此时Spring AOP是不能拦截到这些被嵌套调用的方法的。
//当获取Bean对象使用时//spring容器创建代理对象
IJdkProxyService iJdkProxyService new IJdkProxyServiceImpl();JdkProxyDemoServiceProxy serviceProxy new JdkProxyDemoServiceProxy ()
serviceProxy.setIJdkProxyService(iJdkProxyService);
IJdkProxyService iJdkProxyService (IJdkProxyService) serviceProxy;iJdkProxyService.doMethod1();解决
1、修改类把内部自调用改掉。
2、将this.doMethod2()替换为((IJdkProxyService ) AopContext.currentProxy()).doMethod2()此时需要修改spring的aop配置 // 指示是否创建基于子类(CGLIB)的代理而不是创建基于标准Java接口的代理。 默认值是{code false}。 EnableAspectJAutoProxy(proxyTargetClass true) 3、使用SpringUtil.getBean(iJdkProxyService ).doMethod2()
Component
public class SpringUtil implements ApplicationContextAware {private static ApplicationContext applicationContext;public SpringUtil springUtil() {return new SpringUtil();}Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {if(SpringUtil.applicationContext null) {SpringUtil.applicationContext applicationContext;}}//获取applicationContextpublic static ApplicationContext getApplicationContext() {return applicationContext;}//通过name获取 Bean.public static Object getBean(String name){return getApplicationContext().getBean(name);}//通过class获取Bean.public static T T getBean(ClassT clazz){return getApplicationContext().getBean(clazz);}//通过name,以及Clazz返回指定的Beanpublic static T T getBean(String name,ClassT clazz){return getApplicationContext().getBean(name, clazz);}}