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

spring中的ObjectPostProcessor詳解

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

一、背景

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

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

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

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

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

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

如下的意思:當(dāng)有個(gè)對象實(shí)例實(shí)現(xiàn)了FilterSecurityInterceptor,進(jìn)行對象postProcess增強(qiáng)的時(shí)候被修改屬性咯,達(dá)到一種可以讓開發(fā)者自動增強(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)建的對象,意思就是當(dāng)有一個(gè)對象在調(diào)用postProcess方法后可以給予爭強(qiáng),或者直接替換掉,換一個(gè)新的對象來處理哦。

和之前了解的BeanProcess、BeanFactoryProcess 概念上是差不多的意思,都是針對實(shí)例進(jìn)行爭強(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è)對象的信息。

二、spring security-ObjectPostProcessor

2.1 基本概念

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

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

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

脫離spring容器創(chuàng)建的類實(shí)例,如何把spring容器內(nè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 官方自動配置工程中copy 下來的解釋,非常的容易理解,當(dāng)時(shí)自我本身還是要對于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è)對象Person 被自動裝配咯,afterPropertiesSet這個(gè)生命周期對象的方法也會被處理哦

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

spring security 在配置@EableSecurity 的時(shí)候會自動的將 EnableGlobalAuthentication 裝配,然后裝配@AuthenticationConfiguration,然后導(dǎo)入了@Import(ObjectPostProcessorConfiguration.class),也就是本文中重點(diǎn)了解的一個(gè)對象. 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. 本類不是為了自動裝配的場景,而是在這兩個(gè)注解中使用來手動進(jìn)行Spring Bean 手動裝配的處理哦!

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

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

代碼非常的簡單通過手工的進(jìn)行spring 生命周期的管理,對于有類似spring security這里配置動態(tài)需求比較高的場景需要自己手動的進(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 隨處可見的手動裝配

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

@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)前類中自動注入了**private **ObjectPostProcessor objectObjectPostProcessor;用來初始化spring security中非常重要的對象 WebSecurity **webSecurity,**一個(gè)默認(rèn)的實(shí)現(xiàn)WebSecurityConfigurerAdapter。

WebSecurity的創(chuàng)建

1、Autowired 優(yōu)先級由于@Bean 因此先調(diào)用了這個(gè)自動注入的方法創(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 {
		//自動創(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中有一些自動注入的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,自動配置初始化信息
			// 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手動的初始配置處理的,這種動態(tài)性對于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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

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

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

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

    SpringBoot?Web開發(fā)之請求響應(yīng)、分層解耦問題記錄

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

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

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

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

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

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

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

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

    這篇文章主要介紹了JavaWeb中HttpSession中表單的重復(fù)提交,非常不錯,具有參考借鑒價(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ì),對大家的學(xué)習(xí)或工作有一定的幫助,感興趣的小伙伴可以學(xué)習(xí)一下
    2024-02-02
  • 全面了解Java中的CAS機(jī)制

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

    下面小編就為大家?guī)硪黄媪私釰ava中的CAS機(jī)制。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-10-10
  • Nacos注冊中心的幾種調(diào)用方式詳解

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

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

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

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

最新評論