欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

spring中的ObjectPostProcessor詳解

 更新時(shí)間:2024年01月09日 10:32:30   作者:汪小哥  
這篇文章主要介紹了spring中的ObjectPostProcessor詳解,Spring Security 的 Java 配置不會(huì)公開(kāi)其配置的每個(gè)對(duì)象的每個(gè)屬性,這簡(jiǎn)化了大多數(shù)用戶(hù)的配置,畢竟,如果每個(gè)屬性都公開(kāi),用戶(hù)可以使用標(biāo)準(zhǔn) bean 配置,需要的朋友可以參考下

一、背景

在學(xué)習(xí)spring security的時(shí)候,有了解過(guò)一下官方的文檔,Post Processing Configured Objects 這個(gè)玩意,主要的意思。

Spring Security 的 Java 配置不會(huì)公開(kāi)其配置的每個(gè)對(duì)象的每個(gè)屬性。這簡(jiǎn)化了大多數(shù)用戶(hù)的配置。

畢竟,如果每個(gè)屬性都公開(kāi),用戶(hù)可以使用標(biāo)準(zhǔn) bean 配置。

雖然有充分的理由不直接公開(kāi)每個(gè)屬性,但用戶(hù)可能仍然需要更高級(jí)的配置選項(xiàng)。

為了解決這個(gè)問(wèn)題,Spring Security 引入了,它可以用來(lái)修改或替換 Java 配置創(chuàng)建的許多對(duì)象實(shí)例。

例如,如果要在 filtersecurity攔截器上配置 filtersecuritypublicauthorizationsuccess 屬性,則可以使用。

如下的意思:當(dāng)有個(gè)對(duì)象實(shí)例實(shí)現(xiàn)了FilterSecurityInterceptor,進(jìn)行對(duì)象postProcess增強(qiáng)的時(shí)候被修改屬性咯,達(dá)到一種可以讓開(kāi)發(fā)者自動(dòng)增強(qiáng)的效果。

@Override
protected void configure(HttpSecurity http) throws Exception {
	http
		.authorizeRequests()
			.anyRequest().authenticated()
			.withObjectPostProcessor(new ObjectPostProcessor<FilterSecurityInterceptor>() {
				public <O extends FilterSecurityInterceptor> O postProcess(
						O fsi) {
					fsi.setPublishAuthorizationSuccess(true);
					return fsi;
				}
			});
}

這里有兩個(gè)很關(guān)鍵的字眼,修改或者替換掉Java創(chuàng)建的對(duì)象,意思就是當(dāng)有一個(gè)對(duì)象在調(diào)用postProcess方法后可以給予爭(zhēng)強(qiáng),或者直接替換掉,換一個(gè)新的對(duì)象來(lái)處理哦。

和之前了解的BeanProcess、BeanFactoryProcess 概念上是差不多的意思,都是針對(duì)實(shí)例進(jìn)行爭(zhēng)強(qiáng)的處理,這里的ObjectPostProcessor 和前面兩個(gè)有區(qū)別,不是在spring 聲明周期內(nèi)進(jìn)行的,這個(gè)是通過(guò)人工手工的調(diào)用處理。

有點(diǎn)那種自己創(chuàng)建了一個(gè)new Bean ,然后(自己調(diào)用spring的方法去初始化、去填充屬性)手工的設(shè)置這個(gè)對(duì)象的信息。

二、spring security-ObjectPostProcessor

2.1 基本概念

spring security 中有很多的Bean都不是通過(guò)自動(dòng)的掃描創(chuàng)建的,而是運(yùn)行時(shí)動(dòng)態(tài)的創(chuàng)建,而這個(gè)ObjectPostProcessor進(jìn)行為了運(yùn)行時(shí)動(dòng)態(tài)讓開(kāi)發(fā)者、讓spring security框架本身進(jìn)行相關(guān)數(shù)據(jù)的擴(kuò)展和填充。

這里就有了一個(gè)基本的問(wèn)題?假設(shè),沒(méi)有了自動(dòng)掃描,我們?nèi)绾蝿?chuàng)建一個(gè)Bean呢?

前提一下:這里是在spring 容器初始化完成之后哦,不能在spring 初始化之前自己編程注入BeanDefine 。

脫離spring容器創(chuàng)建的類(lèi)實(shí)例,如何把spring容器內(nèi)的對(duì)象注入到這些類(lèi)實(shí)例內(nèi)呢?

步驟

創(chuàng)建一個(gè)實(shí)例這里就是一些回調(diào),后置處理器增強(qiáng) Initialize the given raw bean, applying factory callbacks such as setBeanName and setBeanFactory, also applying all bean post processors (including ones which might wrap the given raw bean).

org.springframework.beans.factory.config.AutowireCapableBeanFactory#initializeBean

  • Bean 屬性填充 Populate the given bean instance through applying after-instantiation callbacks and bean property post-processing (e.g. for annotation-driven injection).

org.springframework.beans.factory.config.AutowireCapableBeanFactory#autowireBean 其實(shí)這個(gè)都是從Spring 官方自動(dòng)配置工程中copy 下來(lái)的解釋?zhuān)浅5娜菀桌斫猓?dāng)時(shí)自我本身還是要對(duì)于spring的容器機(jī)制有一定的了解喲,才能輕松方便的了解ObjectPostProcessor的實(shí)現(xiàn)原理。

偽代碼

Class ObjectEg implements InitializingBean{
    @Autowire
 	private Person person;
    public void afterPropertiesSet() {
		log.info(person.getName());
	}
}

1、new ObjectEg

2、autowireBeanFactory.initializeBean(objectEg,object.toString())

3、autowireBeanFactory.autowireBean(objectEg)

eg:因此這個(gè)對(duì)象Person 被自動(dòng)裝配咯,afterPropertiesSet這個(gè)生命周期對(duì)象的方法也會(huì)被處理哦

2.2 spring 實(shí)現(xiàn)自動(dòng)手動(dòng)裝配

spring security 在配置@EableSecurity 的時(shí)候會(huì)自動(dòng)的將 EnableGlobalAuthentication 裝配,然后裝配@AuthenticationConfiguration,然后導(dǎo)入了@Import(ObjectPostProcessorConfiguration.class),也就是本文中重點(diǎn)了解的一個(gè)對(duì)象. Spring Configuration that exports the default ObjectPostProcessor. This class is not intended to be imported manually rather it is imported automatically when using EnableWebSecurity or EnableGlobalMethodSecurity. 本類(lèi)不是為了自動(dòng)裝配的場(chǎng)景,而是在這兩個(gè)注解中使用來(lái)手動(dòng)進(jìn)行Spring Bean 手動(dòng)裝配的處理哦!

ObjectPostProcessorConfiguration

org.springframework.security.config.annotation.configuration.ObjectPostProcessorConfiguration

@Configuration(proxyBeanMethods = false)
public class ObjectPostProcessorConfiguration {
	@Bean
	public ObjectPostProcessor<Object> objectPostProcessor(
			AutowireCapableBeanFactory beanFactory) {
		return new AutowireBeanFactoryObjectPostProcessor(beanFactory);
	}
}

AutowireBeanFactoryObjectPostProcessor

對(duì)象自動(dòng)裝配處理的后置處理器哦,通過(guò)手動(dòng)的進(jìn)行管理Allows registering Objects to participate with an AutowireCapableBeanFactory’s post processing of Aware methods, InitializingBean.afterPropertiesSet() , and DisposableBean.destroy().

代碼非常的簡(jiǎn)單通過(guò)手工的進(jìn)行spring 生命周期的管理,對(duì)于有類(lèi)似spring security這里配置動(dòng)態(tài)需求比較高的場(chǎng)景需要自己手動(dòng)的進(jìn)行裝配的可以學(xué)習(xí)了解整個(gè)功能的實(shí)現(xiàn)原理哦。

org.springframework.security.config.annotation.configuration.AutowireBeanFactoryObjectPostProcessor

final class AutowireBeanFactoryObjectPostProcessor
		implements ObjectPostProcessor<Object>, DisposableBean, SmartInitializingSingleton {
	private final Log logger = LogFactory.getLog(getClass());
	private final AutowireCapableBeanFactory autowireBeanFactory;
	private final List<DisposableBean> disposableBeans = new ArrayList<>();
	private final List<SmartInitializingSingleton> smartSingletons = new ArrayList<>();
	AutowireBeanFactoryObjectPostProcessor(
			AutowireCapableBeanFactory autowireBeanFactory) {
		Assert.notNull(autowireBeanFactory, "autowireBeanFactory cannot be null");
		this.autowireBeanFactory = autowireBeanFactory;
	}
	/*
	 * (non-Javadoc)
	 *
	 * @see
	 * org.springframework.security.config.annotation.web.Initializer#initialize(java.
	 * lang.Object)
	 */
	@SuppressWarnings("unchecked")
	public <T> T postProcess(T object) {
		if (object == null) {
			return null;
		}
		T result = null;
		try {
			result = (T) this.autowireBeanFactory.initializeBean(object,
					object.toString());
		}
		catch (RuntimeException e) {
			Class<?> type = object.getClass();
			throw new RuntimeException(
					"Could not postProcess " + object + " of type " + type, e);
		}
		this.autowireBeanFactory.autowireBean(object);
		if (result instanceof DisposableBean) {
			this.disposableBeans.add((DisposableBean) result);
		}
		if (result instanceof SmartInitializingSingleton) {
			this.smartSingletons.add((SmartInitializingSingleton) result);
		}
		return result;
	}
	/* (non-Javadoc)
	 * @see org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated()
	 */
	@Override
	public void afterSingletonsInstantiated() {
		for (SmartInitializingSingleton singleton : smartSingletons) {
			singleton.afterSingletonsInstantiated();
		}
	}
	/*
	 * (non-Javadoc)
	 *
	 * @see org.springframework.beans.factory.DisposableBean#destroy()
	 */
	public void destroy() {
		for (DisposableBean disposable : this.disposableBeans) {
			try {
				disposable.destroy();
			}
			catch (Exception error) {
				this.logger.error(error);
			}
		}
	}
}

2.3 spring security 隨處可見(jiàn)的手動(dòng)裝配

這個(gè)是spring security的入口配置類(lèi),這里重點(diǎn)關(guān)注WebSecurityConfiguration中的手動(dòng)裝配的邏輯,有了之前AutowireBeanFactoryObjectPostProcessor 的了解,對(duì)于這個(gè)裝配邏輯的理解還是十分的簡(jiǎn)單

@Retention(value = java.lang.annotation.RetentionPolicy.RUNTIME)
@Target(value = { java.lang.annotation.ElementType.TYPE })
@Documented
@Import({ WebSecurityConfiguration.class,
		SpringWebMvcImportSelector.class,
		OAuth2ImportSelector.class })
@EnableGlobalAuthentication
@Configuration
public @interface EnableWebSecurity {
	/**
	 * Controls debugging support for Spring Security. Default is false.
	 * @return if true, enables debug support with Spring Security
	 */
	boolean debug() default false;
}

WebSecurityConfiguration

org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration,當(dāng)前類(lèi)中自動(dòng)注入了**private **ObjectPostProcessor objectObjectPostProcessor;用來(lái)初始化spring security中非常重要的對(duì)象 WebSecurity **webSecurity,**一個(gè)默認(rèn)的實(shí)現(xiàn)WebSecurityConfigurerAdapter。

WebSecurity的創(chuàng)建

1、Autowired 優(yōu)先級(jí)由于@Bean 因此先調(diào)用了這個(gè)自動(dòng)注入的方法創(chuàng)建了webSecurityorg.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration#setFilterChainProxySecurityConfigurer,重點(diǎn)是WebSecurity的創(chuàng)建

/**
	 * Sets the {@code <SecurityConfigurer<FilterChainProxy, WebSecurityBuilder>}
	 * instances used to create the web configuration.
	 *
	 * @param objectPostProcessor the {@link ObjectPostProcessor} used to create a
	 * {@link WebSecurity} instance
	 * @param webSecurityConfigurers the
	 * {@code <SecurityConfigurer<FilterChainProxy, WebSecurityBuilder>} instances used to
	 * create the web configuration
	 * @throws Exception
	 */
	@Autowired(required = false)
	public void setFilterChainProxySecurityConfigurer(
			ObjectPostProcessor<Object> objectPostProcessor,
			@Value("#{@autowiredWebSecurityConfigurersIgnoreParents.getWebSecurityConfigurers()}") List<SecurityConfigurer<Filter, WebSecurity>> webSecurityConfigurers)
			throws Exception {
		//自動(dòng)創(chuàng)建了一個(gè)WebSecurity,處理內(nèi)部的注入依賴(lài),通過(guò)objectPostProcessor處理 AutowireBeanFactoryObjectPostProcessor
		webSecurity = objectPostProcessor
				.postProcess(new WebSecurity(objectPostProcessor));
		if (debugEnabled != null) {
			webSecurity.debug(debugEnabled);
		}
		webSecurityConfigurers.sort(AnnotationAwareOrderComparator.INSTANCE);
		Integer previousOrder = null;
		Object previousConfig = null;
		for (SecurityConfigurer<Filter, WebSecurity> config : webSecurityConfigurers) {
			Integer order = AnnotationAwareOrderComparator.lookupOrder(config);
			if (previousOrder != null && previousOrder.equals(order)) {
				throw new IllegalStateException(
						"@Order on WebSecurityConfigurers must be unique. Order of "
								+ order + " was already used on " + previousConfig + ", so it cannot be used on "
								+ config + " too.");
			}
			previousOrder = order;
			previousConfig = config;
		}
		for (SecurityConfigurer<Filter, WebSecurity> webSecurityConfigurer : webSecurityConfigurers) {
			webSecurity.apply(webSecurityConfigurer);
		}
		this.webSecurityConfigurers = webSecurityConfigurers;
	}

WebSecurityConfigurerAdapter的創(chuàng)建

WebSecurityConfigurerAdapter中有一些自動(dòng)注入的Autowired的屬性

/**
	 * Creates the Spring Security Filter Chain
	 * @return the {@link Filter} that represents the security filter chain
	 * @throws Exception
	 */
	@Bean(name = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME)
	public Filter springSecurityFilterChain() throws Exception {
		boolean hasConfigurers = webSecurityConfigurers != null
				&& !webSecurityConfigurers.isEmpty();
		if (!hasConfigurers) {
			//新創(chuàng)建一個(gè)WebSecurityConfigurerAdapter 然后使用objectObjectPostProcessor,自動(dòng)配置初始化信息
			// AutowireBeanFactoryObjectPostProcessor
			WebSecurityConfigurerAdapter adapter = objectObjectPostProcessor
					.postProcess(new WebSecurityConfigurerAdapter() {
					});
			webSecurity.apply(adapter);
		}
        //這里是整個(gè)過(guò)濾鏈條創(chuàng)建的入口哦
		return webSecurity.build();
	}

2.4 spring security 配置

Add this annotation to an @Configuration class to have the Spring Security configuration defined in any WebSecurityConfigurer or more likely by extending the WebSecurityConfigurerAdapter base class and overriding這個(gè)是官方的實(shí)例demo 源碼里面的,WebSecurity、HttpSecurity都是通過(guò)objectObjectPostProcessor手動(dòng)的初始配置處理的,這種動(dòng)態(tài)性對(duì)于spring security本身工程還是擴(kuò)展性提供了良好的擴(kuò)展哦,因此回到了例子,Post Processing Configured Objects 官方文檔里面說(shuō)的那樣子。

   @Configuration
   @EnableWebSecurity
   public class MyWebSecurityConfiguration extends WebSecurityConfigurerAdapter {
   	@Override
   	public void configure(WebSecurity web) throws Exception {
   		web.ignoring()
   		// Spring Security should completely ignore URLs starting with /resources/
   				.antMatchers("/resources/**");
   	}
   	@Override
   	protected void configure(HttpSecurity http) throws Exception {
   		http.authorizeRequests().antMatchers("/public/**").permitAll().anyRequest()
   				.hasRole("USER").and()
   				// Possibly more configuration ...
   				.formLogin() // enable form based log in
   				// set permitAll for all URLs associated with Form Login
   				.permitAll();
   	}
   	@Override
   	protected void configure(AuthenticationManagerBuilder auth) throws Exception {
   		auth
   		// enable in memory based authentication with a user named "user" and "admin"
   		.inMemoryAuthentication().withUser("user").password("password").roles("USER")
   				.and().withUser("admin").password("password").roles("USER", "ADMIN");
   	}
   	// Possibly more overridden methods ...
   }

到此這篇關(guān)于spring中的ObjectPostProcessor詳解的文章就介紹到這了,更多相關(guān)spring的ObjectPostProcessor內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java 調(diào)用Restful API接口的幾種方式(HTTPS)

    Java 調(diào)用Restful API接口的幾種方式(HTTPS)

    這篇文章主要介紹了Java 調(diào)用Restful API接口的幾種方式(HTTPS),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-02-02
  • SpringBoot?Web開(kāi)發(fā)之請(qǐng)求響應(yīng)、分層解耦問(wèn)題記錄

    SpringBoot?Web開(kāi)發(fā)之請(qǐng)求響應(yīng)、分層解耦問(wèn)題記錄

    在?Spring?Boot?的?Web?請(qǐng)求響應(yīng)處理中,Servlet?起著關(guān)鍵的作用,Servlet?是?Java?Web?開(kāi)發(fā)中的基本組件,主要負(fù)責(zé)處理客戶(hù)端的請(qǐng)求并生成響應(yīng),這篇文章主要介紹了SpringBoot?Web開(kāi)發(fā)之請(qǐng)求響應(yīng),分層解耦,需要的朋友可以參考下
    2024-08-08
  • JavaWeb連接數(shù)據(jù)庫(kù)MySQL的操作技巧

    JavaWeb連接數(shù)據(jù)庫(kù)MySQL的操作技巧

    數(shù)據(jù)庫(kù)是編程中重要的一部分,它囊括了數(shù)據(jù)操作,數(shù)據(jù)持久化等各方面。在每一門(mén)編程語(yǔ)言中都占有相當(dāng)大的比例。本次,小編以MySQL為例,使用mvc編程思想,給大家講解下javaweb對(duì)數(shù)據(jù)庫(kù)的操作
    2017-02-02
  • 淺談SpringBoot中的Bean初始化方法?@PostConstruct

    淺談SpringBoot中的Bean初始化方法?@PostConstruct

    這篇文章主要介紹了SpringBoot中的Bean初始化方法?@PostConstruct,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • ElasticSearch查詢(xún)文檔基本操作實(shí)例

    ElasticSearch查詢(xún)文檔基本操作實(shí)例

    這篇文章主要為大家介紹了ElasticSearch查詢(xún)文檔基本操作實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • JavaWeb中HttpSession中表單的重復(fù)提交示例

    JavaWeb中HttpSession中表單的重復(fù)提交示例

    這篇文章主要介紹了JavaWeb中HttpSession中表單的重復(fù)提交,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-03-03
  • 利用Java實(shí)現(xiàn)word導(dǎo)入導(dǎo)出富文本(含圖片)的詳細(xì)代碼

    利用Java實(shí)現(xiàn)word導(dǎo)入導(dǎo)出富文本(含圖片)的詳細(xì)代碼

    這篇文章主要為大家詳細(xì)介紹了利用Java實(shí)現(xiàn)word導(dǎo)入導(dǎo)出富文本(含圖片),文中的示例代碼講解詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,感興趣的小伙伴可以學(xué)習(xí)一下
    2024-02-02
  • 全面了解Java中的CAS機(jī)制

    全面了解Java中的CAS機(jī)制

    下面小編就為大家?guī)?lái)一篇全面了解Java中的CAS機(jī)制。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10
  • Nacos注冊(cè)中心的幾種調(diào)用方式詳解

    Nacos注冊(cè)中心的幾種調(diào)用方式詳解

    Spring Cloud Alibaba Nacos 作為近幾年最熱門(mén)的注冊(cè)中心和配置中心,也被國(guó)內(nèi)無(wú)數(shù)公司所使用,本文就來(lái)看下 Nacos 作為注冊(cè)中心時(shí),調(diào)用它的接口有幾種方式
    2023-10-10
  • Go Java算法之解碼方法示例詳解

    Go Java算法之解碼方法示例詳解

    這篇文章主要為大家介紹了Go Java算法之解碼方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08

最新評(píng)論