@Test public void testWithNoArgConstructor() { NoArgCtorTestBean target = new NoArgCtorTestBean("b", 1); target.reset(); mockTargetSource.setTarget(target); AdvisedSupport pc = new AdvisedSupport(); pc.setTargetSource(mockTargetSource); CglibAopProxy aop = new CglibAopProxy(pc); aop.setConstructorArguments(new Object[] {"Rob Harrop", 22}, new Class<?>[] {String.class, int.class}); NoArgCtorTestBean proxy = (NoArgCtorTestBean) aop.getProxy(); assertNotNull(proxy); }
validateClassIfNecessary(proxySuperClass, classLoader); Enhancer enhancer = createEnhancer(); if (classLoader != null) { enhancer.setClassLoader(classLoader); enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader)); Callback[] callbacks = getCallbacks(rootClass); Class<?>[] types = new Class<?>[callbacks.length]; for (int x = 0; x < types.length; x++) { return createProxyClassAndInstance(enhancer, callbacks);
/** * Checks for final methods on the given {@code Class}, as well as package-visible * methods across ClassLoaders, and writes warnings to the log for each one found. */ private void doValidateClass(Class<?> proxySuperClass, @Nullable ClassLoader proxyClassLoader, Set<Class<?>> ifcs) { if (proxySuperClass != Object.class) { Method[] methods = proxySuperClass.getDeclaredMethods(); for (Method method : methods) { int mod = method.getModifiers(); if (!Modifier.isStatic(mod) && !Modifier.isPrivate(mod)) { if (Modifier.isFinal(mod)) { if (implementsInterface(method, ifcs)) { logger.info("Unable to proxy interface-implementing method [" + method + "] because " + "it is marked as final: Consider using interface-based JDK proxies instead!"); } logger.debug("Final method [" + method + "] cannot get proxied via CGLIB: " + "Calls to this method will NOT be routed to the target instance and " + "might lead to NPEs against uninitialized fields in the proxy instance."); } else if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod) && proxyClassLoader != null && proxySuperClass.getClassLoader() != proxyClassLoader) { logger.debug("Method [" + method + "] is package-visible across different ClassLoaders " + "and cannot get proxied via CGLIB: Declare this method as public or protected " + "if you need to support invocations through the proxy."); } } } doValidateClass(proxySuperClass.getSuperclass(), proxyClassLoader, ifcs); } }
@Test public void testProxyAProxy() { ITestBean target = new TestBean(); mockTargetSource.setTarget(target); AdvisedSupport as = new AdvisedSupport(); as.setTargetSource(mockTargetSource); as.addAdvice(new NopInterceptor()); CglibAopProxy cglib = new CglibAopProxy(as); ITestBean proxy1 = (ITestBean) cglib.getProxy(); mockTargetSource.setTarget(proxy1); as = new AdvisedSupport(new Class<?>[]{}); as.setTargetSource(mockTargetSource); as.addAdvice(new NopInterceptor()); cglib = new CglibAopProxy(as); assertThat(cglib.getProxy(), instanceOf(ITestBean.class)); }
@Override public Object getProxy() { return getProxy(null); }
/** * Checks to see whether the supplied {@code Class} has already been validated and * validates it if not. */ private void validateClassIfNecessary(Class<?> proxySuperClass, @Nullable ClassLoader proxyClassLoader) { if (logger.isWarnEnabled()) { synchronized (validatedClasses) { if (!validatedClasses.containsKey(proxySuperClass)) { doValidateClass(proxySuperClass, proxyClassLoader, ClassUtils.getAllInterfacesForClassAsSet(proxySuperClass)); validatedClasses.put(proxySuperClass, Boolean.TRUE); } } } }
@Override protected AopProxy createAopProxy(AdvisedSupport as) { as.setProxyTargetClass(true); return new CglibAopProxy(as); }
@Test public void testProxyAProxyWithAdditionalInterface() { ITestBean target = new TestBean(); mockTargetSource.setTarget(target); AdvisedSupport as = new AdvisedSupport(); as.setTargetSource(mockTargetSource); as.addAdvice(new NopInterceptor()); as.addInterface(Serializable.class); CglibAopProxy cglib = new CglibAopProxy(as); ITestBean proxy1 = (ITestBean) cglib.getProxy(); mockTargetSource.setTarget(proxy1); as = new AdvisedSupport(new Class<?>[]{}); as.setTargetSource(mockTargetSource); as.addAdvice(new NopInterceptor()); cglib = new CglibAopProxy(as); ITestBean proxy2 = (ITestBean) cglib.getProxy(); assertTrue(proxy2 instanceof Serializable); }
@Override public Object getProxy() { return getProxy(null); }
/** * Checks to see whether the supplied {@code Class} has already been validated and * validates it if not. */ private void validateClassIfNecessary(Class<?> proxySuperClass, @Nullable ClassLoader proxyClassLoader) { if (logger.isWarnEnabled()) { synchronized (validatedClasses) { if (!validatedClasses.containsKey(proxySuperClass)) { doValidateClass(proxySuperClass, proxyClassLoader, ClassUtils.getAllInterfacesForClassAsSet(proxySuperClass)); validatedClasses.put(proxySuperClass, Boolean.TRUE); } } } }
@Test(expected = IllegalArgumentException.class) public void testNullConfig() { new CglibAopProxy(null); }
validateClassIfNecessary(proxySuperClass, classLoader); Enhancer enhancer = createEnhancer(); if (classLoader != null) { enhancer.setClassLoader(classLoader); enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader)); Callback[] callbacks = getCallbacks(rootClass); Class<?>[] types = new Class<?>[callbacks.length]; for (int x = 0; x < types.length; x++) { return createProxyClassAndInstance(enhancer, callbacks);
@Test public void testUnadvisedProxyCreationWithCallDuringConstructor() { CglibTestBean target = new CglibTestBean(); target.setName("Rob Harrop"); AdvisedSupport pc = new AdvisedSupport(); pc.setFrozen(true); pc.setTarget(target); CglibAopProxy aop = new CglibAopProxy(pc); CglibTestBean proxy = (CglibTestBean) aop.getProxy(); assertNotNull("Proxy should not be null", proxy); assertEquals("Constructor overrode the value of name", "Rob Harrop", proxy.getName()); }
/** * Checks for final methods on the given {@code Class}, as well as package-visible * methods across ClassLoaders, and writes warnings to the log for each one found. */ private void doValidateClass(Class<?> proxySuperClass, @Nullable ClassLoader proxyClassLoader, Set<Class<?>> ifcs) { if (proxySuperClass != Object.class) { Method[] methods = proxySuperClass.getDeclaredMethods(); for (Method method : methods) { int mod = method.getModifiers(); if (!Modifier.isStatic(mod) && !Modifier.isPrivate(mod)) { if (Modifier.isFinal(mod)) { if (implementsInterface(method, ifcs)) { logger.info("Unable to proxy interface-implementing method [" + method + "] because " + "it is marked as final: Consider using interface-based JDK proxies instead!"); } logger.debug("Final method [" + method + "] cannot get proxied via CGLIB: " + "Calls to this method will NOT be routed to the target instance and " + "might lead to NPEs against uninitialized fields in the proxy instance."); } else if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod) && proxyClassLoader != null && proxySuperClass.getClassLoader() != proxyClassLoader) { logger.debug("Method [" + method + "] is package-visible across different ClassLoaders " + "and cannot get proxied via CGLIB: Declare this method as public or protected " + "if you need to support invocations through the proxy."); } } } doValidateClass(proxySuperClass.getSuperclass(), proxyClassLoader, ifcs); } }
/** * Checks to see whether the supplied {@code Class} has already been validated and * validates it if not. */ private void validateClassIfNecessary(Class<?> proxySuperClass, ClassLoader proxyClassLoader) { if (logger.isWarnEnabled()) { synchronized (validatedClasses) { if (!validatedClasses.containsKey(proxySuperClass)) { doValidateClass(proxySuperClass, proxyClassLoader, ClassUtils.getAllInterfacesForClassAsSet(proxySuperClass)); validatedClasses.put(proxySuperClass, Boolean.TRUE); } } } }
@Test public void testPackageMethodInvocation() { PackageMethodTestBean bean = new PackageMethodTestBean(); bean.value = "foo"; mockTargetSource.setTarget(bean); AdvisedSupport as = new AdvisedSupport(); as.setTargetSource(mockTargetSource); as.addAdvice(new NopInterceptor()); AopProxy aop = new CglibAopProxy(as); PackageMethodTestBean proxy = (PackageMethodTestBean) aop.getProxy(); assertTrue(AopUtils.isCglibProxy(proxy)); assertEquals(proxy.getClass().getClassLoader(), bean.getClass().getClassLoader()); assertEquals("foo", proxy.getString()); }
validateClassIfNecessary(proxySuperClass, classLoader); Enhancer enhancer = createEnhancer(); if (classLoader != null) { enhancer.setClassLoader(classLoader); enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader)); Callback[] callbacks = getCallbacks(rootClass); Class<?>[] types = new Class<?>[callbacks.length]; for (int x = 0; x < types.length; x++) { return createProxyClassAndInstance(enhancer, callbacks);
/** * Checks for final methods on the given {@code Class}, as well as package-visible * methods across ClassLoaders, and writes warnings to the log for each one found. */ private void doValidateClass(Class<?> proxySuperClass, ClassLoader proxyClassLoader, Set<Class<?>> ifcs) { if (proxySuperClass != Object.class) { Method[] methods = proxySuperClass.getDeclaredMethods(); for (Method method : methods) { int mod = method.getModifiers(); if (!Modifier.isStatic(mod) && !Modifier.isPrivate(mod)) { if (Modifier.isFinal(mod)) { if (implementsInterface(method, ifcs)) { logger.warn("Unable to proxy interface-implementing method [" + method + "] because " + "it is marked as final: Consider using interface-based JDK proxies instead!"); } logger.info("Final method [" + method + "] cannot get proxied via CGLIB: " + "Calls to this method will NOT be routed to the target instance and " + "might lead to NPEs against uninitialized fields in the proxy instance."); } else if (!Modifier.isPublic(mod) && !Modifier.isProtected(mod) && proxyClassLoader != null && proxySuperClass.getClassLoader() != proxyClassLoader) { logger.info("Method [" + method + "] is package-visible across different ClassLoaders " + "and cannot get proxied via CGLIB: Declare this method as public or protected " + "if you need to support invocations through the proxy."); } } } doValidateClass(proxySuperClass.getSuperclass(), proxyClassLoader, ifcs); } }
@Test public void testProtectedMethodInvocation() { ProtectedMethodTestBean bean = new ProtectedMethodTestBean(); bean.value = "foo"; mockTargetSource.setTarget(bean); AdvisedSupport as = new AdvisedSupport(); as.setTargetSource(mockTargetSource); as.addAdvice(new NopInterceptor()); AopProxy aop = new CglibAopProxy(as); ProtectedMethodTestBean proxy = (ProtectedMethodTestBean) aop.getProxy(); assertTrue(AopUtils.isCglibProxy(proxy)); assertEquals(proxy.getClass().getClassLoader(), bean.getClass().getClassLoader()); assertEquals("foo", proxy.getString()); }
@Test public void testMethodInvocationDuringConstructor() { CglibTestBean bean = new CglibTestBean(); bean.setName("Rob Harrop"); AdvisedSupport as = new AdvisedSupport(); as.setTarget(bean); as.addAdvice(new NopInterceptor()); AopProxy aop = new CglibAopProxy(as); CglibTestBean proxy = (CglibTestBean) aop.getProxy(); assertEquals("The name property has been overwritten by the constructor", "Rob Harrop", proxy.getName()); }