如何用MethodBeforeAdvice代理所有@Service并满足安全等需求?
Spring 全局为@Service Bean应用安全代理方案
1. 全局注册Advice到所有@Service Bean
通过定义PointcutAdvisor,将自定义的MethodBeforeAdvice关联到所有标注@Service的Bean上,Spring会自动为这些Bean生成代理:
@Configuration public class ServiceSecurityProxyConfig { @Bean public PointcutAdvisor serviceSecurityAdvisor(MethodBeforeAdvice preAuthorizeAdvice) { // 切点匹配所有@Service标注的Bean及其方法 AnnotationMatchingPointcut pointcut = new AnnotationMatchingPointcut(Service.class, true); DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(); advisor.setPointcut(pointcut); advisor.setAdvice(preAuthorizeAdvice); return advisor; } }
2. 限制仅通过代理访问Service
通过BeanPostProcessor替换原始Service Bean为代理对象,确保IoC容器中只存在代理实例,避免原始Bean被直接获取:
@Component public class ServiceProxyPostProcessor implements BeanPostProcessor { private final MethodBeforeAdvice preAuthorizeAdvice; public ServiceProxyPostProcessor(MethodBeforeAdvice preAuthorizeAdvice) { this.preAuthorizeAdvice = preAuthorizeAdvice; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { Class<?> beanClass = bean.getClass(); // 只处理@Service标注且未被代理的Bean if (beanClass.isAnnotationPresent(Service.class) && !AopUtils.isAopProxy(bean)) { ProxyFactory proxyFactory = new ProxyFactory(bean); proxyFactory.addAdvice(preAuthorizeAdvice); proxyFactory.setProxyTargetClass(true); // 使用CGLIB代理(适配无接口的Service) return proxyFactory.getProxy(); } return bean; } }
此时@Autowired或构造注入获取的都是代理Bean,满足代理可被IoC容器注入的要求。
3. 单元测试脱离代理
单元测试时,可通过以下两种方式直接使用原始Service:
- 使用
@Qualifier("&beanName")获取原始Bean(Spring代理的Bean会以&前缀标识原始实例):
@SpringBootTest class UserServiceTest { @Autowired @Qualifier("&userService") private UserService rawUserService; // 测试逻辑... }
- 在测试配置中禁用代理处理器:
@SpringBootTest class UserServiceTest { @TestConfiguration static class TestProxyDisableConfig { @Bean public ServiceProxyPostProcessor serviceProxyPostProcessor() { return null; // 不注册代理处理器,容器中将保留原始Service Bean } } @Autowired private UserService userService; // 此时注入的是原始Bean // 测试逻辑... }
内容的提问来源于stack exchange,提问作者upi
相关产品推荐
相关产品推荐

