The problem

Adding Shiro invalidates Spring AOP. Spring annotations @aysnc and @cacheable have no effect

Maven imports Shiro dependencies

SpringBoot import Shiro is easy to do by importing shiro-spring-boot-starter

<dependency> <groupId>org.apache.shiro</groupId> <artifactId>shiro-spring-boot-starter</artifactId> The < version > 1.5.2 < / version > < / dependency >Copy the code

Importing Shro-spring-boot-starter requires very little configuration to make Shiro work. It has two auto-assembly classes, ShiroAutoConfiguration, that automatically configure some shiro-related configuration classes ShiroAnnotationProcessorAutoConfiguration class – this class allows Shiro annotations to take effect For example: @ RequiresAuthentication and RequiresPermissions

But is this ShiroAnnotationProcessorAutoConfiguration may conflict and Spring AOP

This error occurs when SpringBoot is started


***************************
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.

Copy the code

This time you will have to stay in ShiroAnnotationProcessorAutoConfiguration SpringBootApplication ruled out

@SpringBootApplication(exclude = {ShiroAnnotationProcessorAutoConfiguration.class})
Copy the code

So you don’t get an error, but some people are using their ShiroConfiguration classes

Joined the

@Bean
@DependsOn("lifecycleBeanPostProcessor")
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
		DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
		defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
		return defaultAdvisorAutoProxyCreator;
}
Copy the code

So do not rule out ShiroAnnotationProcessorAutoConfiguration also won’t complain, but in the dynamic proxy configuration here will lead to Spring AOP failure cause Spring AOP The consequence is that both @enablecaching and @enableAsync become invalid. For example, if you use @async in the method, it still uses the same thread, so the effect of asynchronous execution cannot be achieved

My complete solution

@Configuration
public class ShiroConfiguration {


	@Bean("securityManager") public DefaultWebSecurityManager getManager(JwtRealm realm) { DefaultWebSecurityManager manager = new DefaultWebSecurityManager(); // Use your own realm Manager.setrealm (realm); / * * close shiro's own session, see document * 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(); // Add your own Filter and name it JWT Map<String, Filter> filterMap= new HashMap<>(10); filterMap.put("jwt", new JwtTokenFilter());
		factoryBean.setFilters(filterMap);

		factoryBean.setSecurityManager(securityManager);
		factoryBean.setUnauthorizedUrl("/ 401"); / * * * http://shiro.apache.org/web.html custom url rules#urls-*/ Map<String, String> filterRuleMap = new HashMap<>(10); // All requests are allowed through our own JWT Filter."/ * *"."anon");
		filterRuleMap.put("/ * *"."jwt");
		if(appProperties ! = null && CollUtil.isNotEmpty(appProperties.getIgnoreingUrls())) {for (String ignoreingUrl : appProperties.getIgnoreingUrls()) {
				filterRuleMap.put(ignoreingUrl, "anon");
			}
		}

		factoryBean.setFilterChainDefinitionMap(filterRuleMap);
		returnfactoryBean; // // @conditionalonclass // @dependson ()"lifecycleBeanPostProcessor")
//	public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
//		DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
//		defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
//		returndefaultAdvisorAutoProxyCreator; / / / /} LifecycleBeanPostProcessor leads to Spring AOP failure / / @ Bean / / public LifecycleBeanPostProcessorlifecycleBeanPostProcessor() {
//		return new LifecycleBeanPostProcessor();
//	}
//
	@Bean
	public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
		AuthorizationAttributeSourceAdvisor advisor = new AuthorizationAttributeSourceAdvisor();
		advisor.setSecurityManager(securityManager);
		returnadvisor; }}Copy the code

DefaultAdvisorAutoProxyCreator and LifecycleBeanPostProcessor I comment, these two classes can lead to AOP failure

Because have joined the Spring AOP DefaultAdvisorAutoProxyCreator are required

We simply add spring.aop.proxy-target-class=true to the application.properties configuration file and start class annotation exclusion in SpringBoot ShiroAnnotationProcessorAutoConfiguration

@SpringBootApplication(exclude = {ShiroAnnotationProcessorAutoConfiguration.class})
Copy the code

SPring AOP is now normal and Shiro registries can be used.

conclusion

  1. Cause the AOP try one pit ShiroAnnotationProcessorAutoConfiguration because joined
 @Bean
@DependsOn({"lifecycleBeanPostProcessor"})
@ConditionalOnMissingBean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        return super.defaultAdvisorAutoProxyCreator();
}
Copy the code

Join DefaultAdvisorAutoProxyCreator leads to failure, Spring AOP all @ the class of Service @ Component are not dynamic proxy objects to @ Aysnc and @ Cacheable annotations such as failure

  1. Many of the articles configuration classes that SpringBoot has added to Shiro have been added to the network
@Bean
@ConditionalOnClass
@DependsOn("lifecycleBeanPostProcessor")
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
    DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator = new DefaultAdvisorAutoProxyCreator();
    defaultAdvisorAutoProxyCreator.setProxyTargetClass(true);
}

@Bean
public LifecycleBeanPostProcessor lifecycleBeanPostProcessor() {
	return new LifecycleBeanPostProcessor();
}
Copy the code

LifecycleBeanPostProcessor and DefaultAdvisorAutoProxyCreator will lead to failure, Spring AOP Take effect if you want to make Shiro annotations to join AuthorizationAttributeSourceAdvisor classes and spring configuration spring. The aop) proxy – target – class = true