我对spring不太熟悉,所以也不知道这个需求是不是有点奇怪:现在有个jar包,我们自己写的类继承自jar包里的某个类,平时使用就是new一个对象出来,能不能将jar包里的这个类让spring管理进行aop,这样子类调用父类的方法都能切到?如果spring不行有没有其它方法实现这个需求(对于子类必须是透明的,还是照常new使用,只是调用父类方法能被拦截)?

解决方案 »

  1.   

    使用javasist或者CGlib把你的类增强一下,AOP其实就是动态代理+方法拦截 没什么高深的
      

  2.   

    我想照常用new,不用cglib的方法来获取增强对象也可以么?
      

  3.   

    我想照常用new,不用cglib的方法来获取增强对象也可以么?
    可以的,Spring的AOP太弱了,只能做方法拦截
      

  4.   

    Spring Aop最大的问题其实是,不管你底层用什么实现,能被增强的类“必须得是bean”!也就是不使用ioc容器的话实际上无法使用Spring Aop。还有一个比较明显的问题是,切点表达式不能表达类的继承关系,也就是对于多重重载方法的增强必定局限于某个具体类,其父类和子类都拦截不了。
    类似需求手写也可以做到干净利索,不一定非得依赖于Spring。
    import java.lang.reflect.Method;import net.sf.cglib.proxy.Callback;
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;public class ProxyTest {
    public static void main(String[] args) {
    System.out.println(AdvancedFoo.getInstance().f("b"));
    }
    }class Foo {
    public String f(String s) {
    return s;
    }
    }class AdvancedFoo {
    public static Foo getInstance() {
    Enhancer e = new Enhancer();
    e.setSuperclass(Foo.class);
    e.setCallbacks(new Callback[] { new MethodInterceptor() {
    @Override
    public Object intercept(Object o, Method m, Object[] args,
    MethodProxy mp) throws Throwable {
    args[0] = "a" + args[0];
    return mp.invokeSuper(o, args) + "c";
    }
    }});
    return (Foo) e.create();
    }
    }
      

  5.   

    楼上代码的改进版。这种方案的缺陷是要对已有代码大规模改造,但好处是可以定制,不需要受到AspectJ的各种限制。
    import java.lang.reflect.Method;import net.sf.cglib.proxy.Callback;
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;public class ProxyTest {
    public static void main(String[] args) {
    System.out.println(AdvancedFoo.getInstance().f("b"));
    }
    }class Foo {
    public String f(String s) {
    return s;
    }
    }class AdvancedFoo {
    private static Enhancer e;
    static {
    e = new Enhancer();
    e.setSuperclass(Foo.class);
    e.setCallbacks(new Callback[] { new MethodInterceptor() {
    @Override
    public Object intercept(Object o, Method m, Object[] args,
    MethodProxy mp) throws Throwable {
    args[0] = "a" + args[0];
    return mp.invokeSuper(o, args) + "c";
    }
    }});
    }
    public synchronized static Foo getInstance() {
    return (Foo) e.create();
    }
    }