When building AOP solutions with Spring's ProxyFactoryBean, a few practical limitations quickly surface: each proxy is tied to a single target bean, requiring multiple proxy definitions in large applications; the proxy's own ID must be used when retrieving the bean from the container, rather than the original target bean ID; and advice is applied indiscriminately to every method of the target class. Spring addresses these concerns through Advisor-based pointcuts and automatic proxy creators.
Advisors: Wrapping Advice with Pointcuts
A advisor is a construct that combines an advice (the cross-cutting behavior) with a pointcut that defines exactly where the advice should be applied. The most common advisor type is PointcutAdvisor, which allows the selection of specific join points (methods). Spring provides two ready-to-use implementations:
NameMatchMethodPointcutAdvisor– matches method names directly, with support for explicit lists or wildcard patterns such as*User.RegexpMethodPointcutAdvisor– uses regular expressions to select methods, for example.*add.*to target any method whose name contains "add".
Useful regular expression tokens relevant here are:
.matches any character (except line terminators)..*matches any character sequence..+requires at least one character.*(quantifier) repeats the preceding element zero or more times.
Example Configuration
Assume we have a service interface UserService with methods addUser(), updateUser(), and deleteUser(), and several advice classes: LoggingBeforeAdvice, LoggingAfterAdvice.
<!-- Target bean -->
<bean id="userService" class="com.example.service.impl.UserServiceImpl" />
<!-- Advices -->
<bean id="beforeAdvice" class="com.example.advice.LoggingBeforeAdvice" />
<bean id="afterAdvice" class="com.example.advice.LoggingAfterAdvice" />
<!-- Name-based advisor: before-advice only on addUser -->
<bean id="beforeAdvisor"
class="org.springframework.aop.support.NameMatchMethodPointcutAdvisor">
<property name="advice" ref="beforeAdvice" />
<property name="mappedName" value="addUser" />
</bean>
<!-- Regex-based advisor: after-advice on any method containing 'add' or 'delete' -->
<bean id="afterAdvisor"
class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice" ref="afterAdvice" />
<property name="patterns" value=".*add.*,.*delete.*" />
</bean>
<!-- Manual proxies (limited approach) -->
<bean id="userServiceBeforeProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="userService" />
<property name="interceptorNames" value="beforeAdvisor" />
</bean>
<bean id="userServiceAfterProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="userService" />
<property name="interceptorNames" value="afterAdvisor" />
</bean>
Using manual proxies is06 still verbose. Spring’s auto-proxy craetors eliminate the need to define a proxy for each target/adviser combination.
Automatic Proxy Creators
Auto-proxy creators scan the container and generate proxies automatically based on configured advisors.
DefaultAdvisorAutoProxyCreator
DefaultAdvisorAutoProxyCreator applies every advisor present in the context to every target bean. It is a convenient "one-click" solution but may be too broad.
<bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
Once this is configured, retrieving the original bean by its ID returns a proxy that weaves in all matching advisors. No separate ProxyFactoryBean declarations are needed.
@Test
public void testDefaultAutoProxy() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = ctx.getBean("userService", UserService.class);
userService.addUser(new User()); // triggers beforeAdvisor and afterAdvisor
userService.updateUser(new User()); // triggers afterAdvisor only
}
BeanNameAutoProxyCreator
For finer control, BeanNameAutoProxyCreator lets you select which beans are proxied and which interceptors (advices or advisors) are applied.
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames" value="userService" />
<property name="interceptorNames" value="beforeAdvisor" />
</bean>
The above configuration creates a proxy for userService that weaves in only beforeAdvisor. Multiple bean names and interceptor values are supported via lists.
@Test
public void testBeanNameAutoProxy() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = ctx.getBean("userService", UserService.class);
userService.addUser(new User()); // before-advisor only on addUser
userService.updateUser(new User()); // no advice (updateUser is not matched by beforeAdvisor)
}
dispatchThese auto-proxy strategies remove the16 duplication of proxy definitions and allow retrieval of beans directly by their original IDs9. Together with advisors that precisely target methods, they form a flexible 16 foundation8 for10 AOP0 in1 Spring0 applications.