最近在研究 面向切面编程 这个话题;后来发现Aspectj是AOP 中比较早 的实现。学习中发现我很是不理解的问题:
1.在Eclipse_helio 版本的 ajdt中 使用 aspect 关键字 硬编码 和@Aspect 声明式编码方式 前者能很好运行 后者则出 现了我很不理解的问题..
2.aspectj有自己的编译原理 那么她怎么和普通的项目进行整合?就比如说 建立一个简单的WEB 工程 想在Servlet
里面的doGet 和 doPost 执行之前 进行 页面参数的验证 怎样才能 使*.aj 文件注入 servlet里面
3. aspectj已经出现了很长一段时间了为什么没有流行起来 反倒是 spring 支持Aspectj 的@Annotation 的AOP比较流行?
关于第1个问题 代码:
代码思路是 对pojo的属性进行监控。
pojo(简单的getter setter)
package example.bean.exer.pojo; public class EntityBean{ private String id; private String name; private String descrtion;
package example.bean.exer.pojo; public class Father { private String id;
package example.bean.exer.pojo; public class Sun extends Father { private String name; private int age; private double money;
PropertyChangeListener
package example.bean.exer; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; //@Other public class BeanPropertyListner implements PropertyChangeListener { @Override public void propertyChange(PropertyChangeEvent evt) { // TODO Auto-generated method stub System.out.println("监听 :"+evt.getPropertyName()+" oldValue:"+evt.getOldValue()+" newValue:"+evt.getNewValue()); } }
切面(硬编码)
package example.bean.exer; import java.beans.PropertyChangeSupport; import java.lang.reflect.Method; public aspect BeanAspect { // declare @method :execution(public *.new(..)); // declare @type :example.bean.exer.*:@Enity; // declare parents : (@Enity *) extends Father; public interface PropertyChange{}; //给EntityBean 注入一个support 的属性 private PropertyChangeSupport PropertyChange.support = new PropertyChangeSupport(this); // //给EntityBean 注入一个doSay方法。 public PropertyChangeSupport PropertyChange.getSupport(){ return support; } declare parents :example.bean.exer.pojo.* implements PropertyChange; pointcut testconMethod(): execution(public example.bean.exer.pojo.*.new(..)); before():testconMethod(){ PropertyChange eb=(PropertyChange)thisJoinPoint.getTarget(); eb.support.addPropertyChangeListener(new BeanPropertyListner()); } pointcut testOtherMethod():execution(* example.bean.exer.pojo.*.set*(..)); before():testOtherMethod(){ PropertyChange eb=(PropertyChange)thisJoinPoint.getTarget(); String methodName=thisJoinPoint.getSignature().getName(); String fieldName=methodName.substring(3); String getterName="get"+fieldName; Object o=null; try{ Method m=eb.getClass().getMethod(getterName, null); o=m.invoke(eb, null); }catch(Exception e){ e.printStackTrace(); } eb.support.firePropertyChange(fieldName,o,thisJoinPoint.getArgs()[0]); } }
切面(声明annotation)
package example.bean.exer; import java.beans.PropertyChangeSupport; import java.lang.reflect.Method; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.DeclareParents; import org.aspectj.lang.annotation.Pointcut; @SuppressWarnings("unused") @Aspect public class ModelFieldKeeping { public interface PropertyChange{ PropertyChangeSupport getSupport(); } public static class PropertyChangeImpl implements PropertyChange{ private PropertyChangeSupport support=new PropertyChangeSupport(this); @Override public PropertyChangeSupport getSupport() { // TODO Auto-generated method stub return support; } } @DeclareParents(value="example.bean.exer.pojo.*",defaultImpl=PropertyChangeImpl.class) private PropertyChange implementedInterface; @Pointcut("execution(public example.bean.exer.pojo.*.new(..))") private void constructorMethod(){} @Pointcut("execution(* example.bean.exer.pojo.*.set*(..))") private void setMethod(){} @Before("constructorMethod()") public void addListner(JoinPoint jp){ PropertyChange eb=(PropertyChange)jp.getTarget(); eb.getSupport().addPropertyChangeListener(new BeanPropertyListner()); } @Before("setMethod()") public void fireListner(JoinPoint jp){ PropertyChange eb=(PropertyChange)jp.getTarget(); //fieldName String methodName=jp.getSignature().getName(); String fieldName=jp.getTarget().getClass().getName()+"."+methodName.substring(3); //获取原来值 String getterName="get"+methodName.substring(3); Object o=null; try{ Method m=eb.getClass().getMethod(getterName, null); o=m.invoke(eb, null); }catch(Exception e){ e.printStackTrace(); } eb.getSupport().firePropertyChange(fieldName,o,jp.getArgs()[0]); } }
测试:采用硬编码方式 可以完美输出 但是采用 声明式 则出现 pojo 的方法不能用 我反编译了.class 文件觉得是么的问题的..
package example.bean.exer; import example.bean.exer.pojo.EntityBean; import example.bean.exer.pojo.Father; import example.bean.exer.pojo.Sun; //@Other public class MainTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub EntityBean eb = new EntityBean(); eb.getClass(); eb.setId("sssssssssssss"); eb.setName("ss"); System.out.println(eb.getId()); System.out.println(eb.getName()); Father f = new Father(); System.out.println(f.getSupport()); Sun sun = new Sun(); sun.setAge(9); sun.setId("id。。。"); sun.setMoney(0.1234); sun.setName("hyaci"); System.out.println(sun.getSupport()); } }
以上问题 希望ITeye 的各位朋友 帮忙解决...谢