最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring中的ObjectPostProcessor詳解

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

一、背景

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

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

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

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

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

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

如下的意思:當(dāng)有個(gè)對(duì)象實(shí)例實(shí)現(xiàn)了FilterSecurityInterceptor,進(jìn)行對(duì)象postProcess增強(qiáng)的時(shí)候被修改屬性咯,達(dá)到一種可以讓開發(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ì)象來處理哦。

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

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

二、spring security-ObjectPostProcessor

2.1 基本概念

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

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

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

脫離spring容器創(chuàng)建的類實(shí)例,如何把spring容器內(nèi)的對(duì)象注入到這些類實(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 下來的解釋,非常的容易理解,當(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. 本類不是為了自動(dòng)裝配的場(chǎng)景,而是在這兩個(gè)注解中使用來手動(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)裝配處理的后置處理器哦,通過手動(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)單通過手工的進(jìn)行spring 生命周期的管理,對(duì)于有類似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 隨處可見的手動(dòng)裝配

這個(gè)是spring security的入口配置類,這里重點(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)前類中自動(dòng)注入了**private **ObjectPostProcessor objectObjectPostProcessor;用來初始化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)部的注入依賴,通過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è)過濾鏈條創(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都是通過objectObjectPostProcessor手動(dòng)的初始配置處理的,這種動(dòng)態(tài)性對(duì)于spring security本身工程還是擴(kuò)展性提供了良好的擴(kuò)展哦,因此回到了例子,Post Processing Configured Objects 官方文檔里面說的那樣子。

   @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)文章

  • Docker與Kubernetes部署Java應(yīng)用容器化實(shí)踐指南

    Docker與Kubernetes部署Java應(yīng)用容器化實(shí)踐指南

    容器化是一種將應(yīng)用程序及其依賴打包成一個(gè)可移植的單元的方法,容器能夠在任何環(huán)境中運(yùn)行,并且具有隔離性、可擴(kuò)展性和高效性,這篇文章主要介紹了Docker與Kubernetes部署Java應(yīng)用容器化實(shí)踐指南的相關(guān)資料
    2026-05-05
  • java 中同步、異步、阻塞和非阻塞區(qū)別詳解

    java 中同步、異步、阻塞和非阻塞區(qū)別詳解

    這篇文章主要介紹了java 中同步、異步、阻塞和非阻塞區(qū)別詳解的相關(guān)資料,需要的朋友可以參考下
    2017-04-04
  • mybatis Invalid bound statement(not found)排坑記錄

    mybatis Invalid bound statement(not foun

    這篇文章主要介紹了mybatis Invalid bound statement(not found)排坑記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • HotSpot的Java對(duì)象模型之Oop-Klass模型詳解

    HotSpot的Java對(duì)象模型之Oop-Klass模型詳解

    這篇文章主要介紹了HotSpot的Java對(duì)象模型之Oop-Klass模型詳解,在JVM層面,不僅Java類是對(duì)象,Java 方法也是對(duì)象, 字節(jié)碼常量池也是對(duì)象,一切皆是對(duì)象,JVM使用不同的oop-klass模型來表示各種不同的對(duì)象,需要的朋友可以參考下
    2023-08-08
  • 使用spring的restTemplate注意點(diǎn)

    使用spring的restTemplate注意點(diǎn)

    這篇文章主要介紹了使用spring的restTemplate注意點(diǎn),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-10-10
  • Mybatis-Plus?動(dòng)態(tài)表名的實(shí)踐

    Mybatis-Plus?動(dòng)態(tài)表名的實(shí)踐

    本文主要介紹了Mybatis-Plus?動(dòng)態(tài)表名的實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • java.lang.Runtime.exec的左膀右臂:流輸入和流讀取詳解

    java.lang.Runtime.exec的左膀右臂:流輸入和流讀取詳解

    這篇文章主要介紹了java.lang.Runtime.exec的左膀右臂:流輸入和流讀取詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Spring Cloud負(fù)載均衡及遠(yuǎn)程調(diào)用實(shí)現(xiàn)詳解

    Spring Cloud負(fù)載均衡及遠(yuǎn)程調(diào)用實(shí)現(xiàn)詳解

    這篇文章主要介紹了Spring Cloud負(fù)載均衡及遠(yuǎn)程調(diào)用實(shí)現(xiàn)詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-08-08
  • Java如何使用httpclient檢測(cè)url狀態(tài)及鏈接是否能打開

    Java如何使用httpclient檢測(cè)url狀態(tài)及鏈接是否能打開

    這篇文章主要介紹了Java如何使用httpclient檢測(cè)url狀態(tài)及鏈接是否能打開,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java調(diào)用Windows命令的兩種方法詳解

    Java調(diào)用Windows命令的兩種方法詳解

    在開發(fā)過程中,我們有時(shí)需要通過Java程序來執(zhí)行一些操作系統(tǒng)級(jí)別的任務(wù),本文將詳細(xì)介紹如何使用這兩種方法來調(diào)用Windows命令,并提供示例代碼,有需要的可以了解下
    2025-11-11

最新評(píng)論

怀安县| 乃东县| 类乌齐县| 太仆寺旗| 虞城县| 理塘县| 钟祥市| 广昌县| 阿鲁科尔沁旗| 温泉县| 聂拉木县| 常德市| 汉寿县| 沈阳市| 乌什县| 仙居县| 西宁市| 龙海市| 托克逊县| 大方县| 莱芜市| 桐乡市| 麻江县| 南京市| 华坪县| 介休市| 庆云县| 凌源市| 日照市| 织金县| 岚皋县| 高平市| 庆元县| 桓台县| 泸溪县| 绿春县| 历史| 盘山县| 逊克县| 射阳县| 崇明县|