@Test public void testAutoProxyCreatorWithFactoryBeanAndProxyFactoryBeanOnly() { StaticApplicationContext sac = new StaticApplicationContext(); MutablePropertyValues pvs = new MutablePropertyValues(); pvs.add("proxyObject", "false"); sac.registerSingleton("testAutoProxyCreator", TestAutoProxyCreator.class, pvs); pvs = new MutablePropertyValues(); pvs.add("singleton", "false"); sac.registerSingleton("prototypeFactoryToBeProxied", DummyFactory.class, pvs); sac.refresh(); TestAutoProxyCreator tapc = (TestAutoProxyCreator) sac.getBean("testAutoProxyCreator"); tapc.testInterceptor.nrOfInvocations = 0; FactoryBean<?> prototypeFactory = (FactoryBean<?>) sac.getBean("&prototypeFactoryToBeProxied"); assertTrue(AopUtils.isCglibProxy(prototypeFactory)); TestBean tb = (TestBean) sac.getBean("prototypeFactoryToBeProxied"); assertFalse(AopUtils.isCglibProxy(tb)); assertEquals(2, tapc.testInterceptor.nrOfInvocations); tb.getAge(); assertEquals(2, tapc.testInterceptor.nrOfInvocations); }
@Test public void testCustomAutoProxyCreator() { StaticApplicationContext sac = new StaticApplicationContext(); sac.registerSingleton("testAutoProxyCreator", TestAutoProxyCreator.class); sac.registerSingleton("singletonNoInterceptor", TestBean.class); sac.registerSingleton("singletonToBeProxied", TestBean.class); sac.registerPrototype("prototypeToBeProxied", TestBean.class); sac.refresh(); MessageSource messageSource = (MessageSource) sac.getBean("messageSource"); ITestBean singletonNoInterceptor = (ITestBean) sac.getBean("singletonNoInterceptor"); ITestBean singletonToBeProxied = (ITestBean) sac.getBean("singletonToBeProxied"); ITestBean prototypeToBeProxied = (ITestBean) sac.getBean("prototypeToBeProxied"); assertFalse(AopUtils.isCglibProxy(messageSource)); assertTrue(AopUtils.isCglibProxy(singletonNoInterceptor)); assertTrue(AopUtils.isCglibProxy(singletonToBeProxied)); assertTrue(AopUtils.isCglibProxy(prototypeToBeProxied)); TestAutoProxyCreator tapc = (TestAutoProxyCreator) sac.getBean("testAutoProxyCreator"); assertEquals(0, tapc.testInterceptor.nrOfInvocations); singletonNoInterceptor.getName(); assertEquals(0, tapc.testInterceptor.nrOfInvocations); singletonToBeProxied.getAge(); assertEquals(1, tapc.testInterceptor.nrOfInvocations); prototypeToBeProxied.getSpouse(); assertEquals(2, tapc.testInterceptor.nrOfInvocations); }
private Class<?> getTargetClass(Object targetObject) { Class<?> targetClass = targetObject.getClass(); if (AopUtils.isAopProxy(targetObject)) { targetClass = AopUtils.getTargetClass(targetObject); if (targetClass == targetObject.getClass()) { try { // Maybe a proxy with no target - e.g. gateway Class<?>[] interfaces = ((Advised) targetObject).getProxiedInterfaces(); if (interfaces != null && interfaces.length == 1) { targetClass = interfaces[0]; } } catch (Exception e) { if (logger.isDebugEnabled()) { logger.debug("Exception trying to extract interface", e); } } } } else if (org.springframework.util.ClassUtils.isCglibProxyClass(targetClass)) { Class<?> superClass = targetObject.getClass().getSuperclass(); if (!Object.class.equals(superClass)) { targetClass = superClass; } } return targetClass; }
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean instanceof AopInfrastructureBean) { // Ignore AOP infrastructure such as scoped proxies. return bean; } Class<?> targetClass = AopUtils.getTargetClass(bean); if (targetClass == null) { // Can't do much here. return bean; } if (AopUtils.canApply(this.asyncAnnotationAdvisor, targetClass)) { if (bean instanceof Advised) { ((Advised) bean).addAdvisor(this.asyncAnnotationAdvisor); return bean; } else { ProxyFactory proxyFactory = new ProxyFactory(bean); // Copy our properties (proxyTargetClass etc) inherited from ProxyConfig. proxyFactory.copyFrom(this); proxyFactory.addAdvisor(this.asyncAnnotationAdvisor); return proxyFactory.getProxy(this.beanClassLoader); } } else { // No async proxy needed. return bean; } }
@Test public void testGetAnonymousInnerBeanFromScope() throws Exception { TestBean bean = (TestBean) this.beanFactory.getBean("outerBean"); assertFalse(AopUtils.isAopProxy(bean)); assertTrue(AopUtils.isCglibProxy(bean.getSpouse())); BeanDefinition beanDef = this.beanFactory.getBeanDefinition("outerBean"); BeanDefinitionHolder innerBeanDef = (BeanDefinitionHolder) beanDef.getPropertyValues().getPropertyValue("spouse").getValue(); String name = innerBeanDef.getBeanName(); MockHttpServletRequest request = new MockHttpServletRequest(); RequestAttributes requestAttributes = new ServletRequestAttributes(request); RequestContextHolder.setRequestAttributes(requestAttributes); try { assertNull(request.getAttribute("scopedTarget." + name)); assertEquals("scoped", bean.getSpouse().getName()); assertNotNull(request.getAttribute("scopedTarget." + name)); assertEquals(TestBean.class, request.getAttribute("scopedTarget." + name).getClass()); assertEquals("scoped", ((TestBean) request.getAttribute("scopedTarget." + name)).getName()); } finally { RequestContextHolder.setRequestAttributes(null); } }
public static Class<?> getGenericTypeFromBean(Object object) { Class<?> clazz = object.getClass(); if (AopUtils.isAopProxy(object)) { clazz = AopUtils.getTargetClass(object); } return getGenericType(clazz); }
/** * 获取目标对象. * * @param proxy 代理对象 * @return 目标对象 */ public static Object getTarget(final Object proxy) { if (!AopUtils.isAopProxy(proxy)) { return proxy; } if (AopUtils.isJdkDynamicProxy(proxy)) { return getProxyTargetObject(proxy, "h"); } else { return getProxyTargetObject(proxy, "CGLIB$CALLBACK_0"); } }
/** * 获取 目标对象 * * @param proxy 代理对象 * @return * @throws Exception */ public static Object getTarget(Object proxy) throws Exception { if (!AopUtils.isAopProxy(proxy)) { return proxy; // 不是代理对象 } if (AopUtils.isJdkDynamicProxy(proxy)) { return getJdkDynamicProxyTargetObject(proxy); } else { // cglib return getCglibProxyTargetObject(proxy); } }
/** {@InheritDoc} */ @Override public List<BeanDetail> getBeanDetails() { if (this.allBeans == null) { // initialize BeanDetail list List<BeanDetail> beans = new ArrayList<BeanDetail>(); BeanDetail springBeanDetail; // get the list of bean names List<String> names = this.getBeanNames(); for (String beanName : names) { springBeanDetail = new BeanDetail(); springBeanDetail.setBeanName(beanName); Object bean; String beanType; springBeanDetail.setAliases(Arrays.asList(this.ctx.getAliases(beanName))); bean = this.ctx.getBean(beanName); beanType = bean.getClass().getName(); // Manage proxied beans // If the bean is proxied then its type is modiified. We // detect // it and get the correct target type if (AopUtils.isAopProxy(bean)) { beanType = AopUtils.getTargetClass(bean).getName(); springBeanDetail.setProxied(true); } springBeanDetail.setBeanType(beanType); springBeanDetail.setPrototype(this.ctx.isPrototype(beanName)); springBeanDetail.setSingleton(this.ctx.isSingleton(beanName)); springBeanDetail.setBean(this.ctx.getBean(beanName)); if (this.configurablebeanFactory != null) { BeanDefinition beanDefinition = this.configurablebeanFactory.getBeanDefinition(beanName); springBeanDetail.setBeanType(beanDefinition.getBeanClassName()); springBeanDetail.setDescription(beanDefinition.getDescription()); springBeanDetail.setScope(beanDefinition.getScope()); springBeanDetail.setLazyInit(beanDefinition.isLazyInit()); springBeanDetail.setAbstract(beanDefinition.isAbstract()); } beans.add(springBeanDetail); } this.allBeans = beans; } return this.allBeans; }
@Override public Object postProcessAfterInitialization(final Object bean, final String beanName) throws BeansException { Class<?> targetClass = AopUtils.getTargetClass(bean); final RabbitListener classLevelListener = AnnotationUtils.findAnnotation(bean.getClass(), RabbitListener.class); final List<Method> multiMethods = new ArrayList<Method>(); ReflectionUtils.doWithMethods( targetClass, new ReflectionUtils.MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { RabbitListener rabbitListener = AnnotationUtils.getAnnotation(method, RabbitListener.class); if (rabbitListener != null) { processAmqpListener(rabbitListener, method, bean, beanName); } if (classLevelListener != null) { RabbitHandler rabbitHandler = AnnotationUtils.getAnnotation(method, RabbitHandler.class); if (rabbitHandler != null) { multiMethods.add(method); } } } }); if (classLevelListener != null) { processMultiMethodListener(classLevelListener, multiMethods, bean, beanName); } return bean; }
private void prepareEvaluationContext( StandardEvaluationContext context, Object method, Class<? extends Annotation> annotationType) { Class<?> targetType = AopUtils.getTargetClass(this.targetObject); if (method instanceof Method) { context.registerMethodFilter(targetType, new FixedMethodFilter((Method) method)); if (expectedType != null) { Assert.state( context .getTypeConverter() .canConvert( TypeDescriptor.valueOf(((Method) method).getReturnType()), TypeDescriptor.valueOf(expectedType)), "Cannot convert to expected type (" + expectedType + ") from " + method); } } else if (method == null || method instanceof String) { AnnotatedMethodFilter filter = new AnnotatedMethodFilter(annotationType, (String) method, this.requiresReply); Assert.state( canReturnExpectedType(filter, targetType, context.getTypeConverter()), "Cannot convert to expected type (" + expectedType + ") from " + method); context.registerMethodFilter(targetType, filter); } context.setVariable("target", targetObject); }
/** * Throws an IllegalArgumentException if it encounters a JDK dynamic proxy. Metadata can only be * read from target classes and CGLIB proxies! */ protected void checkManagedBean(Object managedBean) throws IllegalArgumentException { if (AopUtils.isJdkDynamicProxy(managedBean)) { throw new IllegalArgumentException( "MetadataMBeanInfoAssembler does not support JDK dynamic proxies - " + "export the target beans directly or use CGLIB proxies instead"); } }
@Override public Object postProcessAfterInitialization(final Object bean, String beanName) { if (!this.nonAnnotatedClasses.contains(bean.getClass())) { final Set<Method> annotatedMethods = new LinkedHashSet<Method>(1); Class<?> targetClass = AopUtils.getTargetClass(bean); ReflectionUtils.doWithMethods( targetClass, new MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { for (Scheduled scheduled : AnnotationUtils.getRepeatableAnnotation( method, Schedules.class, Scheduled.class)) { processScheduled(scheduled, method, bean); annotatedMethods.add(method); } } }); if (annotatedMethods.isEmpty()) { this.nonAnnotatedClasses.add(bean.getClass()); } } return bean; }
@Test public void withCglibProxy() { ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigWithCglibProxy.class); aspectIsApplied(ctx); assertThat(AopUtils.isCglibProxy(ctx.getBean(FooService.class)), is(true)); }
@Override public boolean matches(Method method, Class<?> targetClass, boolean beanHasIntroductions) { checkReadyToMatch(); Method targetMethod = AopUtils.getMostSpecificMethod(method, targetClass); ShadowMatch shadowMatch = getShadowMatch(targetMethod, method); // Special handling for this, target, @this, @target, @annotation // in Spring - we can optimize since we know we have exactly this class, // and there will never be matching subclass at runtime. if (shadowMatch.alwaysMatches()) { return true; } else if (shadowMatch.neverMatches()) { return false; } else { // the maybe case if (beanHasIntroductions) { return true; } // A match test returned maybe - if there are any subtype sensitive variables // involved in the test (this, target, at_this, at_target, at_annotation) then // we say this is not a match as in Spring there will never be a different // runtime subtype. RuntimeTestWalker walker = getRuntimeTestWalker(shadowMatch); return (!walker.testsSubtypeSensitiveVars() || walker.testTargetInstanceOfResidue(targetClass)); } }
@Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { Method[] methods = AopUtils.getTargetClass(bean).getDeclaredMethods(); for (Method method : methods) { if (method.isAnnotationPresent(MethodLimiter.class)) { MethodLimiter methodLimiter = method.getAnnotation(MethodLimiter.class); // 获取zkclient ZKClusterClient client = ZookeeperClientMakerFactory.getInstance().getZKClusterClient("zkClient"); String name = methodLimiter.name(); int rate = methodLimiter.rate(); // 创建rateLimiter RateLimiterFactory.getInstance().putIfAbsent(name, new RateLimiter().create(name, rate)); String path = PATH_PREFIX + "/" + name; if (!client.isExsit(path)) { // 创建节点 client.createNode( path, String.valueOf(rate), com.foxxy.git.zookeeper.CreateMode.PERSISTENT); } client.registerConnectionListener(new LimiterRateMonitorListener(path)); client.registerNodeListener(path, new LimiterRateMonitorListener(path)); } } return bean; }
/** * Intercept the given method invocation, submit the actual calling of the method to the correct * task executor and return immediately to the caller. * * @param invocation the method to intercept and make asynchronous * @return {@link Future} if the original method returns {@code Future}; {@code null} otherwise. */ public Object invoke(final MethodInvocation invocation) throws Throwable { Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null); Method specificMethod = ClassUtils.getMostSpecificMethod(invocation.getMethod(), targetClass); specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod); Future<?> result = determineAsyncExecutor(specificMethod) .submit( new Callable<Object>() { public Object call() throws Exception { try { Object result = invocation.proceed(); if (result instanceof Future) { return ((Future<?>) result).get(); } } catch (Throwable ex) { ReflectionUtils.rethrowException(ex); } return null; } }); if (Future.class.isAssignableFrom(invocation.getMethod().getReturnType())) { return result; } else { return null; } }
protected void loadArgsAsVariables() { // shortcut if no args need to be loaded if (ObjectUtils.isEmpty(args)) { return; } String key = toString(method); Method targetMethod = methodCache.get(key); if (targetMethod == null) { targetMethod = AopUtils.getMostSpecificMethod(method, targetClass); if (targetMethod == null) { targetMethod = method; } methodCache.put(key, targetMethod); } // save arguments as indexed variables for (int i = 0; i < args.length; i++) { setVariable("p" + i, args[i]); } String[] parameterNames = paramDiscoverer.getParameterNames(targetMethod); // save parameter names (if discovered) if (parameterNames != null) { for (int i = 0; i < parameterNames.length; i++) { setVariable(parameterNames[i], args[i]); } } }
@Test public void testImportXmlWithNamespaceConfig() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(ImportXmlWithAopNamespaceConfig.class); Object bean = ctx.getBean("proxiedXmlBean"); assertTrue(AopUtils.isAopProxy(bean)); }
private Map<String, Object> getHandlerMap(AbstractUrlHandlerMapping mapping) { if (AopUtils.isCglibProxy(mapping)) { // If the AbstractUrlHandlerMapping is a cglib proxy we can't call // the final getHandlerMap() method. return Collections.emptyMap(); } return mapping.getHandlerMap(); }
@SuppressWarnings({"unchecked"}) private <T> T getTargetObject(Object proxy, Class<T> targetClass) throws Exception { if (AopUtils.isJdkDynamicProxy(proxy)) { return (T) ((Advised) proxy).getTargetSource().getTarget(); } else { return (T) proxy; } }
/** * Finds any {@link #equals} or {@link #hashCode} method that may be defined on the supplied set * of interfaces. * * @param proxiedInterfaces the interfaces to introspect */ private void findDefinedEqualsAndHashCodeMethods(Class[] proxiedInterfaces) { for (int i = 0; i < proxiedInterfaces.length; i++) { Class proxiedInterface = proxiedInterfaces[i]; Method[] methods = proxiedInterface.getDeclaredMethods(); for (int j = 0; j < methods.length; j++) { Method method = methods[j]; if (AopUtils.isEqualsMethod(method)) { this.equalsDefined = true; } if (AopUtils.isHashCodeMethod(method)) { this.hashCodeDefined = true; } if (this.equalsDefined && this.hashCodeDefined) { return; } } } }
@Test public void annotatedService_PTC_true() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(PTCTrue.class, NonAnnotatedServiceImpl.class); ctx.refresh(); AnnotatedService s = ctx.getBean(AnnotatedService.class); assertTrue("expected a subclass proxy", AopUtils.isCglibProxy(s)); assertThat(s, instanceOf(NonAnnotatedServiceImpl.class)); }
@Test public void annotatedService_PTC_false() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(PTCFalse.class, NonAnnotatedServiceImpl.class); ctx.refresh(); AnnotatedService s = ctx.getBean(AnnotatedService.class); assertTrue("expected a jdk proxy", AopUtils.isJdkDynamicProxy(s)); assertThat(s, not(instanceOf(NonAnnotatedServiceImpl.class))); }
private Object applyAdvice(Object bean, PointcutAdvisor advisor, ClassLoader beanClassLoader) { Class<?> targetClass = AopUtils.getTargetClass(bean); if (AopUtils.canApply(advisor.getPointcut(), targetClass)) { if (bean instanceof Advised) { ((Advised) bean).addAdvisor(advisor); return bean; } else { ProxyFactory proxyFactory = new ProxyFactory(bean); proxyFactory.addAdvisor(advisor); /** * N.B. it's not a good idea to use proxyFactory.setProxyTargetClass(true) here because it * forces all the integration components to be cglib proxyable (i.e. have a default * constructor etc.), which they are not in general (usually for good reason). */ return proxyFactory.getProxy(beanClassLoader); } } return bean; }
@Test public void transactionProxyIsCreated() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(EnableTxConfig.class, TxManagerConfig.class); ctx.refresh(); TransactionalTestBean bean = ctx.getBean(TransactionalTestBean.class); assertThat("testBean is not a proxy", AopUtils.isAopProxy(bean), is(true)); Map<?, ?> services = ctx.getBeansWithAnnotation(Service.class); assertThat("Stereotype annotation not visible", services.containsKey("testBean"), is(true)); }
@Test public void testAutoProxyCreatorWithFactoryBean() { StaticApplicationContext sac = new StaticApplicationContext(); sac.registerSingleton("testAutoProxyCreator", TestAutoProxyCreator.class); sac.registerSingleton("singletonFactoryToBeProxied", DummyFactory.class); sac.refresh(); TestAutoProxyCreator tapc = (TestAutoProxyCreator) sac.getBean("testAutoProxyCreator"); tapc.testInterceptor.nrOfInvocations = 0; FactoryBean<?> factory = (FactoryBean<?>) sac.getBean("&singletonFactoryToBeProxied"); assertTrue(AopUtils.isCglibProxy(factory)); TestBean tb = (TestBean) sac.getBean("singletonFactoryToBeProxied"); assertTrue(AopUtils.isCglibProxy(tb)); assertEquals(2, tapc.testInterceptor.nrOfInvocations); tb.getAge(); assertEquals(3, tapc.testInterceptor.nrOfInvocations); }
@Test public void proxyingOccurs() { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(AsyncConfig.class); ctx.refresh(); AsyncBean asyncBean = ctx.getBean(AsyncBean.class); assertThat(AopUtils.isAopProxy(asyncBean), is(true)); asyncBean.work(); }
/** * Apply the given AOP method invocation to the given {@link RmiInvocationHandler}. * * <p>The default implementation delegates to {@link #createRemoteInvocation}. * * @param methodInvocation the current AOP method invocation * @param invocationHandler the RmiInvocationHandler to apply the invocation to * @return the invocation result * @throws RemoteException in case of communication errors * @throws NoSuchMethodException if the method name could not be resolved * @throws IllegalAccessException if the method could not be accessed * @throws InvocationTargetException if the method invocation resulted in an exception * @see org.springframework.remoting.support.RemoteInvocation */ protected Object doInvoke( MethodInvocation methodInvocation, RmiInvocationHandler invocationHandler) throws RemoteException, NoSuchMethodException, IllegalAccessException, InvocationTargetException { if (AopUtils.isToStringMethod(methodInvocation.getMethod())) { return "RMI invoker proxy for service URL [" + getJndiName() + "]"; } return invocationHandler.invoke(createRemoteInvocation(methodInvocation)); }
@Test public void withScopedProxyThroughAspectJPattern() throws IOException, ClassNotFoundException { AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); ctx.register(ComponentScanWithScopedProxyThroughAspectJPattern.class); ctx.getBeanFactory().registerScope("myScope", new SimpleMapScope()); ctx.refresh(); // should cast to the interface FooService bean = (FooService) ctx.getBean("scopedProxyTestBean"); // should be dynamic proxy assertThat(AopUtils.isJdkDynamicProxy(bean), is(true)); }