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

  1. Provide a target object: proxyFactory.setTarget(targetInstance) (yields a SingletonTargetSource with a concrete class).
  2. Or provide one or more interfaces: proxyFactory.setInterfaces(MyService.class) so a JDK proxy can be built.
  3. Or set a target class explicitly when there is no instance yet: proxyFactory.setTargetClass(MyService.class).
  4. 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

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


AI-assisted analysis of spring-projects/spring-framework@e8729d0438 (2026-08-04). Data as JSON: /data/errors/408ebf8f680b877e.json. Report an issue: GitHub.