利用Spring AOP中的引入解决java无法多继承问题
2014-01-25 19:36
453 查看
我们知道在java中一个类无法继承多个基类,而有时候,你可能有一组共享公共行为的类,在OOP中,它们必须扩展
相同的基类或者实现相同的接口。这个问题可以用AOP模块化的一个横切关注点。Introduction是AOP中的一种特殊
通知,它允许为一个接口提供实现类使对象动态地实现接口。这样看上去就像使对象在运行时扩展了实现类。而且,你
可以用多个实现类将多个接口同时引入对象。这可以实现与多重继承相同的效果。
例如:我们有两个接口
还有它们的实现类
还有一个用于数学计算的类ArithmeticCalculatorImpl,我们想让该类也执行max()和min()计算。因为Java只支持单继承,让ArithmeticCalculatorImpl
同时扩展MaxCalculatorImpl和MinCalculatorImpl是不可能的,唯一可能的方法是通过复制实现代码或者将处理委派给实际的实现类,扩展某个类比如
MaxCalculatorImpl并实现另个接口比如MinCalculator。在这两种情况下,都必须重新声明方法。
然而。利用引入,就可以实现MaxCalculatorImpl和MinCalculatorImpl动态地实现MaxCalculator和MinCalculator接口。这
和从MaxCalculatorImpl和MinCalculatorImpl多继承有相同的效果。这样做的好处是,不需要修改ArithmeticCalculatorImpl的任何代码,就可以将方法
引入到现有的类中。
然后再bean.xml中注册该类即可,测试如下:
总结:引入怎么能在Spring AOP中做到这一切呢?
答案是动态代理。引入就是通过动态代理添加一个接口(例如MaxCalculator)来工作的。当这个接口中声明的方法在代理对象上调用时,代理
将把调用委派给后端实现类(例如MaxcalculatorImpl)。
相同的基类或者实现相同的接口。这个问题可以用AOP模块化的一个横切关注点。Introduction是AOP中的一种特殊
通知,它允许为一个接口提供实现类使对象动态地实现接口。这样看上去就像使对象在运行时扩展了实现类。而且,你
可以用多个实现类将多个接口同时引入对象。这可以实现与多重继承相同的效果。
例如:我们有两个接口
package calculator; public interface MaxCalculator { public double max(double a,double b); }
package calculator; public interface MinCalculator { public double min(double a,double b); }
还有它们的实现类
package calculator; public class MaxCalculatorImpl implements MaxCalculator { @Override public double max(double a, double b) { // TODO Auto-generated method stub double result = (a>=b) ? a:b; System.out.println("The max is "+result); return result; } }
package calculator; public class MinCalculatorImpl implements MinCalculator { @Override public double min(double a, double b) { double result = (a<=b) ? a:b; System.out.println("The min is "+result); return result; } }
还有一个用于数学计算的类ArithmeticCalculatorImpl,我们想让该类也执行max()和min()计算。因为Java只支持单继承,让ArithmeticCalculatorImpl
同时扩展MaxCalculatorImpl和MinCalculatorImpl是不可能的,唯一可能的方法是通过复制实现代码或者将处理委派给实际的实现类,扩展某个类比如
MaxCalculatorImpl并实现另个接口比如MinCalculator。在这两种情况下,都必须重新声明方法。
然而。利用引入,就可以实现MaxCalculatorImpl和MinCalculatorImpl动态地实现MaxCalculator和MinCalculator接口。这
和从MaxCalculatorImpl和MinCalculatorImpl多继承有相同的效果。这样做的好处是,不需要修改ArithmeticCalculatorImpl的任何代码,就可以将方法
引入到现有的类中。
package calculator; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.DeclareParents; /** * 该类用来引入另一个类已解决java的无法多继承问题 * @author Administrator * */ @Aspect public class CalculatorIntroduction { //@DeclareParents注解类型的value属性表示引入的目标类。 //用于实现这个新接口的实现类在defaultImpl中指定。 @DeclareParents( value="calculator.ArithmeticCalculatorImpl", defaultImpl = MaxCalculatorImpl.class) public MaxCalculator maxCalculator; @DeclareParents( value="calculator.ArithmeticCalculatorImpl", defaultImpl = MinCalculatorImpl.class) public MinCalculator minCalculator; }
然后再bean.xml中注册该类即可,测试如下:
package test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import calculator.ArithmeticCalculator; import calculator.MaxCalculator; public class AspectTest { /** * @param args */ public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml"); ArithmeticCalculator arithmeticCalculator = (ArithmeticCalculator) context.getBean("arithmeticCalculator"); //arithmeticCalculator.add(1,2); //arithmeticCalculator.div(2,0); MaxCalculator maxCalculator = (MaxCalculator) arithmeticCalculator; maxCalculator.max(1,2); } }
总结:引入怎么能在Spring AOP中做到这一切呢?
答案是动态代理。引入就是通过动态代理添加一个接口(例如MaxCalculator)来工作的。当这个接口中声明的方法在代理对象上调用时,代理
将把调用委派给后端实现类(例如MaxcalculatorImpl)。
相关文章推荐
- 利用spring完美解决java中文问题
- (问题解决)Spring @Async无法注入Controller java.lang.NoSuchMethodError: org.objectweb.asm.ClassWriter.<init>(
- java 聚合工程同级相互引入函数问题。interface无法引入与父类相同级别的common中的函数
- java中调用本地动态链接库(*.DLL)的两种方式详解和not found library、打包成jar,war包dll无法加载等等问题解决办法
- Aop拦截Action 使得@Autowired 无法自动装配问题解决
- spring AOP中自身方法调用无法应用代理解决办法
- Android Studio无法利用模板新建Activity与Fragmnet的问题分析与解决
- (转)利用Spring AOP自定义注解解决日志和签名校验
- Spring--java.lang.ClassNotFoundException: org.apache.commons.dbcp2.BasicDataSource问题解决
- Web程序中利用web.config解决无法输出excel页面的问题
- Jps介绍以及解决jps无法查看某个已经启动的java进程问题
- idea上使用maven分模块开发时解决spring注入失败问题java.lang.IllegalStateException: Failed to load ApplicationContext
- 利用Spring AOP自定义注解解决日志和签名校验
- spring 继承的baseDao无法注入导致异常的问题
- JAVA“找不到或无法加载主类” 问题的解决办法
- 无法读取方案文档 'http://www.springframework.org/schema/beans/spring-beans-4.1.xsd'问题解决
- 使用dubbo注解@Service注册服务后使用aop或者申明式事物导致无法注册的问题解决办法
- spring aop编程与ssh集成的奇怪异常问题解决办法
- 关于idea连接docker无法下载docker-java.jar问题解决
- java.lang.ClassNotFoundException:org.springframework.web.context.ContextLoaderListener问题解决