Spring 自动代理创建器详细介绍及简单实例
什么是自动代理创建器
自动代理创建器(Automatic Proxy Creator)是 Spring 框架提供的一种自动创建代理对象的机制。自动代理创建器可以根据配置和规则自动地生成代理对象并加入 Spring 容器,简化了程序员手动创建代理对象的工作。
自动代理的配置方式
Spring 提供了多种方式来配置自动代理:
- 基于 BeanNameAutoProxyCreator 的配置方式
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<value>serviceName1*,serviceName2*</value>
</property>
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>
- 基于 DefaultAdvisorAutoProxyCreator 的配置方式
<bean id="defaultAdvisorAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
<property name="proxyTargetClass" value="true"/>
</bean>
<bean id="transactionInterceptor" class="org.springframework.transaction.interceptor.TransactionInterceptor"/>
<bean id="transactionAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="pointcut">
<bean class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="patterns">
<list>
<value>com.example.*.service.impl.*</value>
</list>
</property>
</bean>
</property>
<property name="advice">
<ref bean="transactionInterceptor"/>
</property>
</bean>
示例
示例1:基于 BeanNameAutoProxyCreator 的自动代理
假设我们有一个 UserService 的接口和其实现类 UserServiceImpl,我们需要为 UserServiceImpl 提供一个事务拦截器进行事务管理,可以使用 BeanNameAutoProxyCreator 进行自动代理。
- 创建 UserService 接口和 UserServiceImpl 实现类
UserService 接口:
public interface UserService {
User addUser(User user);
User getUserById(Long userId);
}
UserServiceImpl 实现类:
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Override
@Transactional
public User addUser(User user) {
userMapper.save(user);
return user;
}
@Override
public User getUserById(Long userId) {
return userMapper.findById(userId);
}
}
其中 UserMapper 是一个 DAO 类,用于数据库操作。
- 创建事务拦截器 TransactionInterceptor
public class CustomTransactionInterceptor extends TransactionInterceptor {
public CustomTransactionInterceptor(PlatformTransactionManager transactionManager, TransactionAttributeSource transactionAttributeSource) {
super.setTransactionManager(transactionManager);
super.setTransactionAttributeSource(transactionAttributeSource);
}
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
TransactionInfo transInfo = createTransactionIfNecessary(getTransactionAttributeSource(), invocation.getMethod(), invocation.getThis().getClass());
Object result = null;
try {
result = invocation.proceed();
} catch (Exception ex) {
completeTransactionAfterThrowing(transInfo, ex);
throw ex;
} finally {
cleanupTransactionInfo(transInfo);
}
commitTransactionAfterReturning(transInfo);
return result;
}
}
- 创建 BeanNameAutoProxyCreator 配置
<bean name="userService" class="com.example.service.impl.UserServiceImpl"/>
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>
<bean id="transactionInterceptor" class="com.example.aop.CustomTransactionInterceptor">
<property name="transactionManager" ref="transactionManager"/>
<property name="transactionAttributeSource">
<bean class="org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"/>
</property>
</bean>
<bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<value>userService</value>
</property>
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>
通过配置 BeanNameAutoProxyCreator,当 Spring 容器中有名为 userService 的 Bean 被创建时,会自动为其创建代理对象并添加事务拦截器。在实际使用中,我们可以在控制器中直接引用 userService Bean,无需再手动创建此 Bean 的代理对象。
示例2:基于 DefaultAdvisorAutoProxyCreator 的自动代理
假设我们有一个 OrderService 的接口和其实现类 OrderServiceImpl,我们需要为 OrderServiceImpl 提供一个日志拦截器进行日志记录,可以使用 DefaultAdvisorAutoProxyCreator 进行自动代理。
- 创建 OrderService 接口和 OrderServiceImpl 实现类
OrderService 接口:
public interface OrderService {
Order addOrder(Order order);
Order getOrderById(Long orderId);
}
OrderServiceImpl 实现类:
@Service
public class OrderServiceImpl implements OrderService {
private static final Logger logger = LoggerFactory.getLogger(OrderServiceImpl.class);
@Autowired
private OrderMapper orderMapper;
@Override
public Order addOrder(Order order) {
logger.info("Add order start: {}", order);
orderMapper.save(order);
logger.info("Add order end: {}", order);
return order;
}
@Override
public Order getOrderById(Long orderId) {
return orderMapper.findById(orderId);
}
}
其中 OrderMapper 是一个 DAO 类,用于数据库操作。
- 创建日志拦截器 LoggingInterceptor
public class LoggingInterceptor implements MethodInterceptor {
private static final Logger logger = LoggerFactory.getLogger(LoggingInterceptor.class);
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
String className = invocation.getThis().getClass().getName();
String methodName = invocation.getMethod().getName();
Object[] args = invocation.getArguments();
logger.info("entering method {}.{}", className, methodName);
logger.info("arguments: {}", Arrays.toString(args));
Object result = invocation.proceed();
logger.info("returning from method {}.{}", className, methodName);
logger.info("result: {}", result);
return result;
}
}
- 创建 DefaultAdvisorAutoProxyCreator 配置
<bean name="orderService" class="com.example.service.impl.OrderServiceImpl"/>
<bean id="loggingInterceptor" class="com.example.aop.LoggingInterceptor"/>
<bean id="loggingAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor">
<property name="pointcut">
<bean class="org.springframework.aop.support.JdkRegexpMethodPointcut">
<property name="patterns">
<list>
<value>com.example.*.service.impl.*</value>
</list>
</property>
</bean>
</property>
<property name="advice">
<ref bean="loggingInterceptor"/>
</property>
</bean>
<bean id="defaultAdvisorAutoProxyCreator" class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
<property name="proxyTargetClass" value="true"/>
</bean>
通过配置 DefaultAdvisorAutoProxyCreator,当 Spring 容器中有包名为 com.example..service.impl. 的 Bean 被创建时,会自动为其创建代理对象并添加日志拦截器。在实际使用中,我们可以在控制器中直接引用 orderService Bean,无需再手动创建此 Bean 的代理对象。
结论
自动代理创建器是 Spring 框架提供的一个非常实用的机制,可以帮助开发者大大简化代码。需要注意的是,在使用时需要根据业务需求进行合理的配置,一般情况下应该将其作为辅助手段,而不是过度依赖。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring 自动代理创建器详细介绍及简单实例 - Python技术站