вопрос
Добавление Широ привело к сбою Spring AOP, а аннотации Spring @Aysnc и @Cacheable не оказали никакого влияния.
Maven импортирует зависимости Shiro
SpringBoot import Shiro очень прост, просто нужно импортировать shiro-spring-boot-starter
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring-boot-starter</artifactId>
<version>1.5.2</version>
</dependency>
Импорт shiro-spring-boot-starter требует очень небольшой настройки, чтобы заставить Shiro работать. Он имеет два класса autowired ShiroAutoConfiguration автоматически настраивает некоторые классы конфигурации, связанные с Shiro. ShiroAnnotationProcessorAutoConfiguration Этот класс позволяет вступать в силу аннотациям Shiro, например: @RequiresAuthentication и RequiresPermissions.
Но именно этот ShiroAnnotationProcessorAutoConfiguration будет конфликтовать со Spring AOP
Эта ошибка возникает при запуске SpringBoot
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'xxxx' could not be injected as a 'com.xxx.xxx' because it is a JDK dynamic proxy that implements:
com.egzosn.pay.common.api.PayMessageHandler
Action:
Consider injecting the bean as one of its interfaces or forcing the use of CGLib-based proxies by setting proxyTargetClass=true on @EnableAsync and/or @EnableCaching.
На этот раз вам нужно исключить ShiroAnnotationProcessorAutoConfiguration в SpringBootApplication.
@SpringBootApplication(exclude = {ShiroAnnotationProcessorAutoConfiguration.class})
Это не сообщит об ошибке, но некоторые люди находятся в своем собственном классе конфигурации Широ (ShiroConfiguration)
присоединился
@Bean
@DependsOn("lifecycleBeanPostProcessor")
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
return defaultAdvisorAutoProxyCreator;
}
Так что не исключено, что ShiroAnnotationProcessorAutoConfiguration не сообщит об ошибке, но настроенный здесь динамический прокси приведет к сбою Spring AOP Причина сбоя Spring AOP. Следствием этого является то, что вы используете @EnableCaching и @EnableAsync для сбоя. Например, если вы используете @Async для метода, он по-прежнему будет использовать тот же поток, что приведет к невозможности достижения эффекта асинхронного выполнения .
мое полное решение
@Configuration
public class ShiroConfiguration {
@Bean("securityManager")
public DefaultWebSecurityManager getManager(JwtRealm realm) {
DefaultWebSecurityManager manager = new DefaultWebSecurityManager();
// 使用自己的realm
manager.setRealm(realm);
/*
* 关闭shiro自带的session,详情见文档
* http://shiro.apache.org/session-management.html#SessionManagement-StatelessApplications%28Sessionless%29
*/
DefaultSubjectDAO subjectDAO = new DefaultSubjectDAO();
DefaultSessionStorageEvaluator defaultSessionStorageEvaluator = new DefaultSessionStorageEvaluator();
// defaultSessionStorageEvaluator.setSessionStorageEnabled(false);
subjectDAO.setSessionStorageEvaluator(defaultSessionStorageEvaluator);
manager.setSubjectDAO(subjectDAO);
return manager;
}
@Bean("shiroFilter")
public ShiroFilterFactoryBean factory(DefaultWebSecurityManager securityManager, AppProperties appProperties) {
ShiroFilterFactoryBean factoryBean = new ShiroFilterFactoryBean();
// 添加自己的过滤器并且取名为jwt
Map<String, Filter> filterMap= new HashMap<>(10);
filterMap.put("jwt", new JwtTokenFilter());
factoryBean.setFilters(filterMap);
factoryBean.setSecurityManager(securityManager);
factoryBean.setUnauthorizedUrl("/401");
/*
* 自定义url规则
* http://shiro.apache.org/web.html#urls-
*/
Map<String, String> filterRuleMap = new HashMap<>(10);
// 所有请求通过我们自己的JWT Filter 全部放行 x.put("/**", "anon");
filterRuleMap.put("/**", "jwt");
if (appProperties != null && CollUtil.isNotEmpty(appProperties.getIgnoreingUrls())) {
for (String ignoreingUrl : appProperties.getIgnoreingUrls()) {
filterRuleMap.put(ignoreingUrl, "anon");
}
}
factoryBean.setFilterChainDefinitionMap(filterRuleMap);
return factoryBean;
}
/**
* 下面的代码是添加注解支持
*/
// @Bean
// @ConditionalOnClass
// @DependsOn("lifecycleBeanPostProcessor")
// public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
// DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
// defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
// return defaultAdvisorAutoProxyCreator;
// }
// LifecycleBeanPostProcessor会导致Spring AOP失效
// @Bean
// public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
// return new LifecycleBeanPostProcessor();
// }
//
@Bean
public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
advisor.setSecurityManager(securityManager);
return advisor;
}
}
Я аннотировал DefaultAdvisorAutoProxyCreator и LifecycleBeanPostProcessor, эти два класса приведут к сбою AOP
Поскольку был добавлен Spring AOP, нет необходимости использовать DefaultAdvisorAutoProxyCreator.
Нам просто нужно настроить файл application.properties присоединяются к spring.aop.proxy-target-class=true Затем исключите ShiroAnnotationProcessorAutoConfiguration в аннотации класса запуска SpringBoot.
@SpringBootApplication(exclude = {ShiroAnnotationProcessorAutoConfiguration.class})
Таким образом, SPring AOP является обычным, и регистрация Широ также может быть использована.
Суммировать
- Одна из ям, которая заставила AOP попробовать ShiroAnnotationProcessorAutoConfiguration из-за присоединения
@Bean
@DependsOn({"lifecycleBeanPostProcessor"})
@ConditionalOnMissingBean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
return super.defaultAdvisorAutoProxyCreator();
}
Добавление DefaultAdvisorAutoProxyCreator приведет к сбою Spring AOP, и все классы @Service @Component не будут динамическими прокси-объектами. Вызывает аннулирование аннотаций, таких как @Aysnc и @Cacheable.
- Многие статьи SpringBoot в Интернете были добавлены в классы конфигурации статей Широ.
@Bean
@ConditionalOnClass
@DependsOn("lifecycleBeanPostProcessor")
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
}
@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
return new LifecycleBeanPostProcessor();
}
Как LifecycleBeanPostProcessor, так и DefaultAdvisorAutoProxyCreator вызовут сбой Spring AOP, Если вы хотите, чтобы аннотация Широ вступила в силу, добавьте класс AuthorizationAttributeSourceAdvisor и конфигурацию spring spring.aop.proxy-target-class=true