J2EE开发中使用AOP技术
在传统的OO面向对象技术中,任何逻辑都需用基于类来封装(这里主要讨论Java技术),随着项目的做大,在管理大量的类文件是非常困难的,而且现在软件提倡的是高层抽象,底层实现,一层一层的架起整个项目,最终体现给程序员的是当实现MVC的时候,就再也不用管理和理会底层的实现,包括数据库DAO层.
Java技术中提供了接口技术,接口就是对某一类事物的抽象,它可以由具体的类implements来实现,但是一个接口可能有多种实现,具体的实现将由程序员的设计不同而不同,如果我们调用接口类型,它到底和哪个实现类想关联呢?
通常情况下:如下:
public interface Interface{
public void say();
}
public class A implements Interface{
public void say(){
System.out.println("this is class A");
}
}
public class B implements Interface{
public void say(){
System.out.println("this is class B");
}
}
现在摆在面前的有一个接口和它的2个实现类,现在根据高层抽象理论,在实现业务逻辑时程序员将不再考虑它的底层实现A或B,但接口做为抽象,没有任何实现,具体是这么关联呢?
这里需要使用的是Spring的AOP技术:
首先定义Spring Ioc applicationContext.xml
<?xml version="1.0" encoding="1.0" ?>
<!DOCTYPE beans
PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-bean.dtd">'
<beans>
<bean id="A" class="A"/>
<bean id="B" class="B"/>
<bean id="Aproxy" class="org.springframework.aop.framework.ProxyBeanFactory">
<property name="proxyInterfaces">
<value>Interface</value>
<property>
<property name="target">
<ref local="A"/>
</property>
</bean>
<bean id="Bproxy" class="org.springframework.aop.framework.ProxyBeanFactory">
<property name="proxyInterfaces">
<value>Interface</value>
</property>
<property name="target">
<value>B</value>
</property>
</bean>
</beans>
具体业务逻辑实现:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test{
public static void main(String[] args){
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
Interface inter=(Interface)context.getBean("Aproxy");
inter.say();
}
}
以上程序将输出" this is class A" 可以看出,做为高层抽象的概念完全体现了出来,在test类中根本就没有A类的任何痕迹.
另外一种AOP技术就是传奇的AspectJ技术.借助与cglib动态字节码生成技术,它可以在不用改写源代码的情况下直接对目标程序进行添加功能.
假设现在有个类 C
public class C {
public void say(){
System.out.println("This is Class C");
}
现在想要给它加个方法 otherSay()用来输出"hello world",传统的机械式方法就是直接修改C的代码,这样做的后果就是造成了C必须被重新编译,但是用AspectJ技术就可以在不用重新编译的情况下直接给C注射一个新方法,具体实现如下:
public interface InterfaceC{
public void otherSay();
}
public aspect D{
declare parents: C extends InterfaceC;
public void C.otherSay(){
System.out.println("hello world");
}
}
现在就可以这样调用:
public class test{
public static void main(String[] dd){
C c=new C();
//执行C的原配方法 say
c.say();
//执行被动态注射后的方法
InterfaceC cc=(InterfaceC)c;
cc.otherSay();
}
}
Java技术中提供了接口技术,接口就是对某一类事物的抽象,它可以由具体的类implements来实现,但是一个接口可能有多种实现,具体的实现将由程序员的设计不同而不同,如果我们调用接口类型,它到底和哪个实现类想关联呢?
通常情况下:如下:
public interface Interface{
public void say();
}
public class A implements Interface{
public void say(){
System.out.println("this is class A");
}
}
public class B implements Interface{
public void say(){
System.out.println("this is class B");
}
}
现在摆在面前的有一个接口和它的2个实现类,现在根据高层抽象理论,在实现业务逻辑时程序员将不再考虑它的底层实现A或B,但接口做为抽象,没有任何实现,具体是这么关联呢?
这里需要使用的是Spring的AOP技术:
首先定义Spring Ioc applicationContext.xml
<?xml version="1.0" encoding="1.0" ?>
<!DOCTYPE beans
PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-bean.dtd">'
<beans>
<bean id="A" class="A"/>
<bean id="B" class="B"/>
<bean id="Aproxy" class="org.springframework.aop.framework.ProxyBeanFactory">
<property name="proxyInterfaces">
<value>Interface</value>
<property>
<property name="target">
<ref local="A"/>
</property>
</bean>
<bean id="Bproxy" class="org.springframework.aop.framework.ProxyBeanFactory">
<property name="proxyInterfaces">
<value>Interface</value>
</property>
<property name="target">
<value>B</value>
</property>
</bean>
</beans>
具体业务逻辑实现:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class test{
public static void main(String[] args){
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
Interface inter=(Interface)context.getBean("Aproxy");
inter.say();
}
}
以上程序将输出" this is class A" 可以看出,做为高层抽象的概念完全体现了出来,在test类中根本就没有A类的任何痕迹.
另外一种AOP技术就是传奇的AspectJ技术.借助与cglib动态字节码生成技术,它可以在不用改写源代码的情况下直接对目标程序进行添加功能.
假设现在有个类 C
public class C {
public void say(){
System.out.println("This is Class C");
}
现在想要给它加个方法 otherSay()用来输出"hello world",传统的机械式方法就是直接修改C的代码,这样做的后果就是造成了C必须被重新编译,但是用AspectJ技术就可以在不用重新编译的情况下直接给C注射一个新方法,具体实现如下:
public interface InterfaceC{
public void otherSay();
}
public aspect D{
declare parents: C extends InterfaceC;
public void C.otherSay(){
System.out.println("hello world");
}
}
现在就可以这样调用:
public class test{
public static void main(String[] dd){
C c=new C();
//执行C的原配方法 say
c.say();
//执行被动态注射后的方法
InterfaceC cc=(InterfaceC)c;
cc.otherSay();
}
}