Spring Boot присоединяется к яме, из-за которой Широ вызывает сбой AOP

Spring Boot

вопрос

Добавление Широ привело к сбою 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 является обычным, и регистрация Широ также может быть использована.

Суммировать

  1. Одна из ям, которая заставила AOP попробовать ShiroAnnotationProcessorAutoConfiguration из-за присоединения
 @Bean
@DependsOn({"lifecycleBeanPostProcessor"})
@ConditionalOnMissingBean
public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() {
        return super.defaultAdvisorAutoProxyCreator();
}

Добавление DefaultAdvisorAutoProxyCreator приведет к сбою Spring AOP, и все классы @Service @Component не будут динамическими прокси-объектами. Вызывает аннулирование аннотаций, таких как @Aysnc и @Cacheable.

  1. Многие статьи 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