From 296aa96d715ccc56ab12cbc5af27004e127489a1 Mon Sep 17 00:00:00 2001 From: Juergen Hoeller Date: Mon, 22 Mar 2010 18:31:13 +0000 Subject: [PATCH] AopUtils.getTargetClass(...) never returns null (SPR-7011) --- .../springframework/aop/support/AopUtils.java | 32 ++++++++++--------- .../springframework/jmx/support/JmxUtils.java | 30 ++++++++--------- .../AsyncAnnotationBeanPostProcessor.java | 16 +++------- .../ScheduledAnnotationBeanPostProcessor.java | 8 ++--- ...enceExceptionTranslationPostProcessor.java | 12 ++----- 5 files changed, 41 insertions(+), 57 deletions(-) diff --git a/org.springframework.aop/src/main/java/org/springframework/aop/support/AopUtils.java b/org.springframework.aop/src/main/java/org/springframework/aop/support/AopUtils.java index 429d6ce153..2dc9d58bb9 100644 --- a/org.springframework.aop/src/main/java/org/springframework/aop/support/AopUtils.java +++ b/org.springframework.aop/src/main/java/org/springframework/aop/support/AopUtils.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -85,7 +85,7 @@ public abstract class AopUtils { * Check whether the specified class is a CGLIB-generated class. * @param clazz the class to check */ - public static boolean isCglibProxyClass(Class clazz) { + public static boolean isCglibProxyClass(Class clazz) { return (clazz != null && isCglibProxyClassName(clazz.getName())); } @@ -102,18 +102,20 @@ public abstract class AopUtils { * which might be an AOP proxy. *

Returns the target class for an AOP proxy and the plain class else. * @param candidate the instance to check (might be an AOP proxy) - * @return the target class (or the plain class of the given object as fallback) + * @return the target class (or the plain class of the given object as fallback; + * never null) * @see org.springframework.aop.TargetClassAware#getTargetClass() */ - public static Class getTargetClass(Object candidate) { + public static Class getTargetClass(Object candidate) { Assert.notNull(candidate, "Candidate object must not be null"); + Class result = null; if (candidate instanceof TargetClassAware) { - return ((TargetClassAware) candidate).getTargetClass(); + result = ((TargetClassAware) candidate).getTargetClass(); } - if (isCglibProxy(candidate)) { - return candidate.getClass().getSuperclass(); + if (result == null) { + result = (isCglibProxy(candidate) ? candidate.getClass().getSuperclass() : candidate.getClass()); } - return candidate.getClass(); + return result; } /** @@ -165,7 +167,7 @@ public abstract class AopUtils { * targetClass doesn't implement it or is null * @see org.springframework.util.ClassUtils#getMostSpecificMethod */ - public static Method getMostSpecificMethod(Method method, Class targetClass) { + public static Method getMostSpecificMethod(Method method, Class targetClass) { Method resolvedMethod = ClassUtils.getMostSpecificMethod(method, targetClass); // If we are dealing with method with generic parameters, find the original method. return BridgeMethodResolver.findBridgedMethod(resolvedMethod); @@ -180,7 +182,7 @@ public abstract class AopUtils { * @param targetClass the class to test * @return whether the pointcut can apply on any method */ - public static boolean canApply(Pointcut pc, Class targetClass) { + public static boolean canApply(Pointcut pc, Class targetClass) { return canApply(pc, targetClass, false); } @@ -194,7 +196,7 @@ public abstract class AopUtils { * for this bean includes any introductions * @return whether the pointcut can apply on any method */ - public static boolean canApply(Pointcut pc, Class targetClass, boolean hasIntroductions) { + public static boolean canApply(Pointcut pc, Class targetClass, boolean hasIntroductions) { if (!pc.getClassFilter().matches(targetClass)) { return false; } @@ -207,7 +209,7 @@ public abstract class AopUtils { Set classes = new HashSet(ClassUtils.getAllInterfacesForClassAsSet(targetClass)); classes.add(targetClass); - for (Class clazz : classes) { + for (Class clazz : classes) { Method[] methods = clazz.getMethods(); for (Method method : methods) { if ((introductionAwareMethodMatcher != null && @@ -229,7 +231,7 @@ public abstract class AopUtils { * @param targetClass class we're testing * @return whether the pointcut can apply on any method */ - public static boolean canApply(Advisor advisor, Class targetClass) { + public static boolean canApply(Advisor advisor, Class targetClass) { return canApply(advisor, targetClass, false); } @@ -243,7 +245,7 @@ public abstract class AopUtils { * any introductions * @return whether the pointcut can apply on any method */ - public static boolean canApply(Advisor advisor, Class targetClass, boolean hasIntroductions) { + public static boolean canApply(Advisor advisor, Class targetClass, boolean hasIntroductions) { if (advisor instanceof IntroductionAdvisor) { return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass); } @@ -265,7 +267,7 @@ public abstract class AopUtils { * @return sublist of Advisors that can apply to an object of the given class * (may be the incoming List as-is) */ - public static List findAdvisorsThatCanApply(List candidateAdvisors, Class clazz) { + public static List findAdvisorsThatCanApply(List candidateAdvisors, Class clazz) { if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } diff --git a/org.springframework.context/src/main/java/org/springframework/jmx/support/JmxUtils.java b/org.springframework.context/src/main/java/org/springframework/jmx/support/JmxUtils.java index 159f2b347e..dd008404df 100644 --- a/org.springframework.context/src/main/java/org/springframework/jmx/support/JmxUtils.java +++ b/org.springframework.context/src/main/java/org/springframework/jmx/support/JmxUtils.java @@ -237,7 +237,7 @@ public abstract class JmxUtils { * @return the bean class to expose * @see org.springframework.util.ClassUtils#getUserClass(Object) */ - public static Class getClassToExpose(Object managedBean) { + public static Class getClassToExpose(Object managedBean) { return ClassUtils.getUserClass(managedBean); } @@ -247,12 +247,12 @@ public abstract class JmxUtils { * (for example, checked for annotations). *

This implementation returns the superclass for a CGLIB proxy and * the class of the given bean else (for a JDK proxy or a plain bean class). - * @param beanClass the bean class (might be an AOP proxy class) + * @param clazz the bean class (might be an AOP proxy class) * @return the bean class to expose * @see org.springframework.util.ClassUtils#getUserClass(Class) */ - public static Class getClassToExpose(Class beanClass) { - return ClassUtils.getUserClass(beanClass); + public static Class getClassToExpose(Class clazz) { + return ClassUtils.getUserClass(clazz); } /** @@ -260,14 +260,14 @@ public abstract class JmxUtils { *

This implementation checks for {@link javax.management.DynamicMBean} * classes as well as classes with corresponding "*MBean" interface * (Standard MBeans) or corresponding "*MXBean" interface (Java 6 MXBeans). - * @param beanClass the bean class to analyze + * @param clazz the bean class to analyze * @return whether the class qualifies as an MBean * @see org.springframework.jmx.export.MBeanExporter#isMBean(Class) */ - public static boolean isMBean(Class beanClass) { - return (beanClass != null && - (DynamicMBean.class.isAssignableFrom(beanClass) || - (getMBeanInterface(beanClass) != null || getMXBeanInterface(beanClass) != null))); + public static boolean isMBean(Class clazz) { + return (clazz != null && + (DynamicMBean.class.isAssignableFrom(clazz) || + (getMBeanInterface(clazz) != null || getMXBeanInterface(clazz) != null))); } /** @@ -277,13 +277,13 @@ public abstract class JmxUtils { * @param clazz the class to check * @return the Standard MBean interface for the given class */ - public static Class getMBeanInterface(Class clazz) { - if (clazz.getSuperclass() == null) { + public static Class getMBeanInterface(Class clazz) { + if (clazz == null || clazz.getSuperclass() == null) { return null; } String mbeanInterfaceName = clazz.getName() + MBEAN_SUFFIX; Class[] implementedInterfaces = clazz.getInterfaces(); - for (Class iface : implementedInterfaces) { + for (Class iface : implementedInterfaces) { if (iface.getName().equals(mbeanInterfaceName)) { return iface; } @@ -298,12 +298,12 @@ public abstract class JmxUtils { * @param clazz the class to check * @return whether there is an MXBean interface for the given class */ - public static Class getMXBeanInterface(Class clazz) { - if (clazz.getSuperclass() == null) { + public static Class getMXBeanInterface(Class clazz) { + if (clazz == null || clazz.getSuperclass() == null) { return null; } Class[] implementedInterfaces = clazz.getInterfaces(); - for (Class iface : implementedInterfaces) { + for (Class iface : implementedInterfaces) { boolean isMxBean = iface.getName().endsWith(MXBEAN_SUFFIX); if (mxBeanAnnotationAvailable) { Boolean checkResult = MXBeanChecker.evaluateMXBeanAnnotation(iface); diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationBeanPostProcessor.java b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationBeanPostProcessor.java index 93672399b5..6eacaf0a0a 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationBeanPostProcessor.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/AsyncAnnotationBeanPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,13 +17,13 @@ package org.springframework.scheduling.annotation; import java.lang.annotation.Annotation; +import java.util.concurrent.Executor; import org.springframework.aop.framework.Advised; import org.springframework.aop.framework.AopInfrastructureBean; import org.springframework.aop.framework.ProxyConfig; import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.support.AopUtils; -import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.config.BeanPostProcessor; @@ -32,8 +32,6 @@ import org.springframework.core.task.TaskExecutor; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import java.util.concurrent.Executor; - /** * Bean post-processor that automatically applies asynchronous invocation * behavior to any bean that carries the {@link Async} annotation at class or @@ -105,22 +103,16 @@ public class AsyncAnnotationBeanPostProcessor extends ProxyConfig } - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + public Object postProcessBeforeInitialization(Object bean, String beanName) { return bean; } - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + public Object postProcessAfterInitialization(Object bean, String beanName) { 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); diff --git a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java index a4d1a410d8..f76c997351 100644 --- a/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java +++ b/org.springframework.context/src/main/java/org/springframework/scheduling/annotation/ScheduledAnnotationBeanPostProcessor.java @@ -21,7 +21,6 @@ import java.util.HashMap; import java.util.Map; import org.springframework.aop.support.AopUtils; -import org.springframework.beans.BeansException; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.context.ApplicationContext; @@ -82,15 +81,12 @@ public class ScheduledAnnotationBeanPostProcessor implements BeanPostProcessor, } - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + public Object postProcessBeforeInitialization(Object bean, String beanName) { return bean; } - public Object postProcessAfterInitialization(final Object bean, String beanName) throws BeansException { + public Object postProcessAfterInitialization(final Object bean, String beanName) { Class targetClass = AopUtils.getTargetClass(bean); - if (targetClass == null) { - return bean; - } ReflectionUtils.doWithMethods(targetClass, new MethodCallback() { public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { Scheduled annotation = AnnotationUtils.getAnnotation(method, Scheduled.class); diff --git a/org.springframework.transaction/src/main/java/org/springframework/dao/annotation/PersistenceExceptionTranslationPostProcessor.java b/org.springframework.transaction/src/main/java/org/springframework/dao/annotation/PersistenceExceptionTranslationPostProcessor.java index 46b0d689c2..df8ec516d2 100644 --- a/org.springframework.transaction/src/main/java/org/springframework/dao/annotation/PersistenceExceptionTranslationPostProcessor.java +++ b/org.springframework.transaction/src/main/java/org/springframework/dao/annotation/PersistenceExceptionTranslationPostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2009 the original author or authors. + * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -106,22 +106,16 @@ public class PersistenceExceptionTranslationPostProcessor extends ProxyConfig } - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { + public Object postProcessBeforeInitialization(Object bean, String beanName) { return bean; } - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { + public Object postProcessAfterInitialization(Object bean, String beanName) { 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.persistenceExceptionTranslationAdvisor, targetClass)) { if (bean instanceof Advised) { ((Advised) bean).addAdvisor(this.persistenceExceptionTranslationAdvisor); -- GitLab