spring-projects/spring-framework · error · AopConfigException
TargetSource cannot determine target class: Either an…
Error message
TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.
What it means
Thrown by DefaultAopProxyFactory.createAopProxy when a CGLIB/class proxy is requested (optimize, proxyTargetClass, or no user interfaces) but the AdvisedSupport has neither a target class nor any proxied interfaces. The factory cannot decide what to subclass or implement, so it refuses to build a proxy. This is a configuration-time guard that fails fast instead of producing a useless proxy.
Solutions
- Set a target or TargetSource on the proxy config before getProxy(), e.g. factory.setTarget(myBean) or factory.setTargetSource(ts) where ts.getTargetClass() is non-null.
- Alternatively call factory.setInterfaces(MyInterface.class) so a JDK dynamic proxy is built instead of a class proxy.
- If using @Enable* annotations with proxyTargetClass, ensure the target bean is resolvable (not a missing/lazy bean with null class).
- Drop optimize/proxyTargetClass so the JDK path applies when only interfaces are available.
Example fix
// before ProxyFactory pf = new ProxyFactory(); pf.addAdvice(myInterceptor); pf.setProxyTargetClass(true); Object proxy = pf.getProxy(); // -> TargetSource cannot determine target class // after ProxyFactory pf = new ProxyFactory(); pf.setTarget(new MyServiceImpl()); pf.addAdvice(myInterceptor); pf.setProxyTargetClass(true); Object proxy = pf.getProxy();
Defensive patterns
Strategy: validation
Validate before calling
// Validate before getProxy()
ProxyCreatorSupport cfg = factory; // your AdvisedSupport / ProxyFactory
boolean needsClass = cfg.isOptimize() || cfg.isProxyTargetClass() || !cfg.hasUserSuppliedInterfaces();
if (needsClass && cfg.getTargetClass() == null && cfg.getProxiedInterfaces().length == 0) {
throw new IllegalStateException(
"Refusing to build proxy: CGLIB mode with no target class and no interfaces.");
} Type guard
static boolean canBuildProxy(AdvisedSupport c) {
boolean classMode = c.isOptimize() || c.isProxyTargetClass() || !c.hasUserSuppliedInterfaces();
return !classMode || c.getTargetClass() != null || c.getProxiedInterfaces().length > 0;
} Try / catch
try { proxy = factory.getProxy(); }
catch (AopConfigException e) {
if (e.getMessage().contains("cannot determine target class")) { /* set target or interfaces, then retry build */ }
else throw e;
} Prevention
- Always pair setProxyTargetClass(true) with a concrete setTarget/setTargetSource.
- When relying on autodetect interfaces, ensure a target bean is resolvable before getProxy().
- In tests, assert factory.getTargetClass() != null before calling getProxy().
When it happens
Trigger: Hit when (config.isOptimize() || config.isProxyTargetClass() || !config.hasUserSuppliedInterfaces()) is true AND config.getTargetClass() == null AND config.getProxiedInterfaces().length == 0. Concretely: new ProxyFactory().setProxyTargetClass(true) with no setTarget/setTargetSource/setInterfaces; or @EnableAsync(proxyTargetClass=true) on a bean whose TargetSource returns null target class (lazy/scoped proxy where the target bean is not resolvable yet).
Common situations: Forcing proxyTargetClass=true on an interface-only or target-less ProxyFactory; scoped-proxy/lazy-init targets whose TargetSource.getTargetClass() returns null because the backing bean does not exist yet; programmatic ProxyFactory use where setTarget was forgotten; upgrading and adding @EnableTransactionManagement(proxyTargetClass=true) while still expecting JDK interface proxies.
Related errors
- Cannot create class proxy for TargetSource with null target…
- Could not generate CGLIB subclass of
- Need to invoke method
- Unable to instantiate proxy using Objenesis, and regular…
- Unexpected AOP exception
AI-assisted analysis of spring-projects/spring-framework@69bf83ad71 (2026-08-09).
Data as JSON: /api/errors/408ebf8f680b877e.
Report an issue: GitHub.
Appendix: source
Thrown at spring-aop/src/main/java/org/springframework/aop/framework/DefaultAopProxyFactory.java:64
* @see AdvisedSupport#setInterfaces
*/
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
/**
* Singleton instance of this class.
* @since 6.0.10
*/
public static final DefaultAopProxyFactory INSTANCE = new DefaultAopProxyFactory();
private static final long serialVersionUID = 7930414337282325166L;
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || !config.hasUserSuppliedInterfaces()) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null && config.getProxiedInterfaces().length == 0) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass == null || targetClass.isInterface() ||
Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
}
View on GitHub (pinned to 69bf83ad71)