/** * Return an introduction advisor mixin that allows the AOP proxy to be * cast to ThreadLocalInvokerStats. */ public IntroductionAdvisor getStatsMixin() { DelegatingIntroductionInterceptor dii = new DelegatingIntroductionInterceptor(this); return new DefaultIntroductionAdvisor(dii, ThreadLocalTargetSourceStats.class); }
public DynamicAsyncInterfaceBean() { ProxyFactory pf = new ProxyFactory(new HashMap<>()); DefaultIntroductionAdvisor advisor = new DefaultIntroductionAdvisor(new MethodInterceptor() { @Override public Object invoke(MethodInvocation invocation) throws Throwable { assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); if (Future.class.equals(invocation.getMethod().getReturnType())) { return new AsyncResult<>(invocation.getArguments()[0].toString()); } return null; } }); advisor.addInterface(AsyncInterface.class); pf.addAdvisor(advisor); this.proxy = (AsyncInterface) pf.getProxy(); }
/** * Create a DefaultIntroductionAdvisor for the given advice. * @param advice the Advice to apply * @param intf the interface to introduce */ public DefaultIntroductionAdvisor(DynamicIntroductionAdvice advice, Class<?> intf) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; addInterface(intf); }
/** * Wrap the given interceptor and introduce all interfaces. */ public DefaultIntroductionAdvisor(Advice advice, IntroductionInfo introductionInfo) { init(advice, introductionInfo); }
/** * Create a DefaultIntroductionAdvisor for the given advice. * @param advice the Advice to apply * @param introductionInfo the IntroductionInfo that describes * the interface to introduce (may be {@code null}) */ public DefaultIntroductionAdvisor(Advice advice, @Nullable IntroductionInfo introductionInfo) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; if (introductionInfo != null) { Class<?>[] introducedInterfaces = introductionInfo.getInterfaces(); if (introducedInterfaces.length == 0) { throw new IllegalArgumentException("IntroductionAdviceSupport implements no interfaces"); } for (Class<?> ifc : introducedInterfaces) { addInterface(ifc); } } }
public DefaultIntroductionAdvisor(Advice advice) { if (advice instanceof IntroductionInfo) { init(advice, (IntroductionInfo) advice); } else { this.advice = advice; } }
/** * Return an IntroductionAdvisor that providing a mixin * exposing statistics about the pool maintained by this object. */ public DefaultIntroductionAdvisor getPoolingConfigMixin() { DelegatingIntroductionInterceptor dii = new DelegatingIntroductionInterceptor(this); return new DefaultIntroductionAdvisor(dii, PoolingConfig.class); }
public DynamicAsyncMethodsInterfaceBean() { ProxyFactory pf = new ProxyFactory(new HashMap<>()); DefaultIntroductionAdvisor advisor = new DefaultIntroductionAdvisor(new MethodInterceptor() { @Override public Object invoke(MethodInvocation invocation) throws Throwable { assertTrue(!Thread.currentThread().getName().equals(originalThreadName)); if (Future.class.equals(invocation.getMethod().getReturnType())) { return new AsyncResult<>(invocation.getArguments()[0].toString()); } return null; } }); advisor.addInterface(AsyncMethodsInterface.class); pf.addAdvisor(advisor); this.proxy = (AsyncMethodsInterface) pf.getProxy(); }
public DefaultIntroductionAdvisor(DynamicIntroductionAdvice advice, Class clazz) { this.advice = advice; addInterface(clazz); }
/** * Create a new advisor that will expose the given bean name, introducing * the NamedBean interface to make the bean name accessible without forcing * the target object to be aware of this Spring IoC concept. * @param beanName the bean name to expose */ public static Advisor createAdvisorIntroducingNamedBean(String beanName) { return new DefaultIntroductionAdvisor(new ExposeBeanNameIntroduction(beanName)); }
/** * Create a DefaultIntroductionAdvisor for the given advice. * @param advice the Advice to apply * @param intf the interface to introduce */ public DefaultIntroductionAdvisor(DynamicIntroductionAdvice advice, Class<?> intf) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; addInterface(intf); }
/** * Cannot add introductions this way unless the advice implements IntroductionInfo. */ @Override public void addAdvice(int pos, Advice advice) throws AopConfigException { Assert.notNull(advice, "Advice must not be null"); if (advice instanceof IntroductionInfo) { // We don't need an IntroductionAdvisor for this kind of introduction: // It's fully self-describing. addAdvisor(pos, new DefaultIntroductionAdvisor(advice, (IntroductionInfo) advice)); } else if (advice instanceof DynamicIntroductionAdvice) { // We need an IntroductionAdvisor for this kind of introduction. throw new AopConfigException("DynamicIntroductionAdvice may only be added as part of IntroductionAdvisor"); } else { addAdvisor(pos, new DefaultPointcutAdvisor(advice)); } }
/** * Create a DefaultIntroductionAdvisor for the given advice. * @param advice the Advice to apply * @param intf the interface to introduce */ public DefaultIntroductionAdvisor(DynamicIntroductionAdvice advice, Class<?> intf) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; addInterface(intf); }
@Test public void testIntroductionMasksTargetImplementation() throws Exception { final long t = 1001L; @SuppressWarnings("serial") class TestII extends DelegatingIntroductionInterceptor implements TimeStamped { @Override public long getTimeStamp() { return t; } } DelegatingIntroductionInterceptor ii = new TestII(); // != t TestBean target = new TargetClass(t + 1); ProxyFactory pf = new ProxyFactory(target); pf.addAdvisor(0, new DefaultIntroductionAdvisor(ii)); TimeStamped ts = (TimeStamped) pf.getProxy(); // From introduction interceptor, not target assertTrue(ts.getTimeStamp() == t); }
private void init(Advice advice, IntroductionInfo introductionInfo) { this.advice = advice; Class[] introducedInterfaces = introductionInfo.getInterfaces(); if (introducedInterfaces.length == 0) { throw new IllegalArgumentException("IntroductionAdviceSupport implements no interfaces"); } for (int i = 0; i < introducedInterfaces.length; i++) { addInterface(introducedInterfaces[i]); } }
@Test public void testUseAsHashKey() { TestBean target1 = new TestBean(); ProxyFactory pf1 = new ProxyFactory(target1); pf1.addAdvice(new NopInterceptor()); ITestBean proxy1 = (ITestBean) createProxy(pf1); TestBean target2 = new TestBean(); ProxyFactory pf2 = new ProxyFactory(target2); pf2.addAdvisor(new DefaultIntroductionAdvisor(new TimestampIntroductionInterceptor())); ITestBean proxy2 = (ITestBean) createProxy(pf2); HashMap<ITestBean, Object> h = new HashMap<>(); Object value1 = "foo"; Object value2 = "bar"; assertNull(h.get(proxy1)); h.put(proxy1, value1); h.put(proxy2, value2); assertEquals(h.get(proxy1), value1); assertEquals(h.get(proxy2), value2); }
/** * Create a DefaultIntroductionAdvisor for the given advice. * @param advice the Advice to apply * @param introductionInfo the IntroductionInfo that describes * the interface to introduce (may be {@code null}) */ public DefaultIntroductionAdvisor(Advice advice, @Nullable IntroductionInfo introductionInfo) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; if (introductionInfo != null) { Class<?>[] introducedInterfaces = introductionInfo.getInterfaces(); if (introducedInterfaces.length == 0) { throw new IllegalArgumentException("IntroductionAdviceSupport implements no interfaces"); } for (Class<?> ifc : introducedInterfaces) { addInterface(ifc); } } }
@SuppressWarnings("serial") @Test public void testIntroductionInterceptorDoesntReplaceToString() throws Exception { TestBean raw = new TestBean(); assertTrue(! (raw instanceof TimeStamped)); ProxyFactory factory = new ProxyFactory(raw); TimeStamped ts = new SerializableTimeStamped(0); factory.addAdvisor(0, new DefaultIntroductionAdvisor(new DelegatingIntroductionInterceptor(ts) { @Override public String toString() { throw new UnsupportedOperationException("Shouldn't be invoked"); } })); TimeStamped tsp = (TimeStamped) factory.getProxy(); assertEquals(0, tsp.getTimeStamp()); assertEquals(raw.toString(), tsp.toString()); }
/** * Create a DefaultIntroductionAdvisor for the given advice. * @param advice the Advice to apply * @param introductionInfo the IntroductionInfo that describes * the interface to introduce (may be {@code null}) */ public DefaultIntroductionAdvisor(Advice advice, IntroductionInfo introductionInfo) { Assert.notNull(advice, "Advice must not be null"); this.advice = advice; if (introductionInfo != null) { Class<?>[] introducedInterfaces = introductionInfo.getInterfaces(); if (introducedInterfaces.length == 0) { throw new IllegalArgumentException("IntroductionAdviceSupport implements no interfaces"); } for (Class<?> ifc : introducedInterfaces) { addInterface(ifc); } } }
/** * Should only be able to introduce interfaces, not classes. */ @Test public void testCannotAddIntroductionAdviceToIntroduceClass() throws Throwable { TestBean target = new TestBean(); target.setAge(21); ProxyFactory pc = new ProxyFactory(target); try { pc.addAdvisor(0, new DefaultIntroductionAdvisor(new TimestampIntroductionInterceptor(), TestBean.class)); fail("Shouldn't be able to add introduction advice that introduces a class, rather than an interface"); } catch (IllegalArgumentException ex) { assertTrue(ex.getMessage().contains("interface")); } // Check it still works: proxy factory state shouldn't have been corrupted ITestBean proxied = (ITestBean) createProxy(pc); assertEquals(target.getAge(), proxied.getAge()); }