spring-projects/spring-framework · error · AopConfigException
TargetSource cannot determine target class: Either an interf
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, in the CGLIB branch (optimize || proxyTargetClass || no user-supplied interfaces), both the target class and the proxied interfaces are absent. To create any proxy Spring needs at least one of: a concrete target class to subclass, or interfaces to implement. With neither, neither CGLIB nor JDK proxying is possible, so the factory aborts up front.
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 e8729d0438)
Solutions
- Provide a target object: proxyFactory.setTarget(targetInstance) (yields a SingletonTargetSource with a concrete class).
- Or provide one or more interfaces: proxyFactory.setInterfaces(MyService.class) so a JDK proxy can be built.
- Or set a target class explicitly when there is no instance yet: proxyFactory.setTargetClass(MyService.class).
- Audit the ProxyFactory build sequence to ensure setTarget/setInterfaces is called before getProxy().
Example fix
// before ProxyFactory pf = new ProxyFactory(); pf.addAdvice(myAdvice); Object proxy = pf.getProxy(); // throws: no target, no interfaces // after ProxyFactory pf = new ProxyFactory(); pf.setInterfaces(MyService.class); pf.addAdvice(myAdvice); MyService proxy = (MyService) pf.getProxy();
Defensive patterns
Strategy: validation
Validate before calling
ProxyFactory pf = new ProxyFactory();
// before getProxy():
boolean hasTarget = pf.getTargetClass() != null;
boolean hasInterfaces = pf.getProxiedInterfaces().length > 0;
if (!hasTarget && !hasInterfaces) {
throw new IllegalStateException(
"ProxyFactory has neither target class nor interfaces; cannot create a proxy");
} Prevention
- Always set a target or at least one interface on ProxyFactory before getProxy().
- Use setTargetClass when you have no instance yet but know the class.
- Add a startup integration test to catch missing-target proxy beans early.
When it happens
Trigger: Building a ProxyFactory with neither setTarget/setTargetSource nor setInterfaces, then calling getProxy(); a TargetSource whose getTargetClass() returns null combined with an empty interface list; an interceptor-only proxy configured without any interface (which would be needed for a JDK proxy) and no target.
Common situations: Creating 'stateless' interceptor proxies without specifying an interface to expose; misconfigured AspectJ proxies; programmatic ProxyFactory that forgot to set the target or interfaces; EmptyTargetSource with no class.
Related errors
- MethodInvocation is not a Spring ProxyMethodInvocation: {}
- 'argumentNames' property of AbstractAspectJAdvice contains a
- Only afterReturning advice can be used to bind a return valu
- Only afterThrowing advice can be used to bind a thrown excep
- Advice method [{}] requires {} arguments to be bound by name
AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04).
Data as JSON: /data/errors/408ebf8f680b877e.json.
Report an issue: GitHub.