It is reasonable to say that the new objects and the container are not related, but in the Spring Security framework also new a lot of objects out, but also can be managed by the container. How is this done?
In the Spring Security authorization configuration code of some projects, you will find a line of code like this.
|
|
What exactly is the meaning of withObjectPostProcessor
here?
1. The role of ObjectPostProcessor
Let’s take a look at what ObjectPostProcessor
really does, starting with the definition of this interface.
There is only one postProcess
method in the interface.
Let’s look at the inheritance relationship of ObjectPostProcessor
.
Two more important implementation classes, of which AutowireBeanFactoryObjectPostProcessor
is worth talking about, take a look at the definition of AutowireBeanFactoryObjectPostProcessor
.
|
|
The source code of AutowireBeanFactoryObjectPostProcessor
is well understood.
- First of all, when building the
AutowireBeanFactoryObjectPostProcessor
object, anAutowireCapableBeanFactory
object is passed in, and if you have seen the Spring source code, you know thatAutowireCapableBeanFactory
can help us manually register an instance into the Spring container. - In the postProcess method, is the specific registration logic, are very simple, I will not repeat.
On a macro level, AutowireCapableBeanFactory provides the following capabilities.
- assembling properties for objects that have been instantiated with property objects that are managed by Spring.
- instantiate a bean and automatically assemble it, these assembled property objects are managed by Spring, but the instantiated bean can be not managed by Spring (this is especially important). So this interface provides functionality is automatically assembled bean related.
(The original object for auto-assembly can be outside of Spring’s IOC container, but the member that needs to be injected must be a bean governed by the Spring container)
This interface is primarily intended for applications outside of the framework that do not host beans to Spring. By exposing this functionality, applications outside of the Spring Framework can have the ability to auto-assemble (which this interface gives it).
You can use this interface to integrate with other frameworks. Bind and populate (inject) instances that are not managed by Spring lifecycle and already exist. Like the integration of WebWork Actions
and Tapestry Page
is very practical. General application developers will not use this interface , so the appearance of implementation classes like ApplicationContext
will not implement this interface , but provides getAutowireCapableBeanFactory()
method allows you to take this tool to do what you need .
As you can see, the main role of the ObjectPostProcessor
is to manually register the instance into the Spring container (and let the instance go through the bean’s lifecycle).
Normally, the beans in our project are injected into the Spring container through automatic scanning, however, in the Spring Security framework, there is a large amount of code that is not injected into the Spring container through automatic scanning, but directly new out, which is intended to simplify the project configuration.
These directly new out of the code, if you want to be managed by the Spring container what to do? Then you have to use ObjectPostProcessor
.
2. Use cases in the framework
The next few examples of the framework directly new object
, we look at the role of ObjectPostProcessor
.
HttpSecurity
initialization code (WebSecurityConfigurerAdapter#getHttp
).
WebSecurity
initialization code (WebSecurityConfiguration#setFilterChainProxySecurityConfigurer
).
|
|
Manual assembly is seen everywhere in the Spring Security framework source code. all filters in the filter chain in Spring Security are configured through the corresponding xxxConfigure, which all inherit from the SecurityConfigurerAdapter
. as follows.
The configure methods of these xxxConfigure invariably have their respective configured managers registered in the Spring container and go through the bean’s lifecycle. For example, the AbstractAuthenticationFilterConfigurer#configure
method.
The other xxxConfigurer#configure
methods all have similar implementations.
3. Why is this
Isn’t it better to register the bean directly to the Spring container via auto-scan? Why do we have to do this?
In Spring Security, the framework itself uses a lot of Java configuration and does not expose all the properties of the object, which is intended to simplify the configuration. However, one of the problems this brings is the need to manually register the bean into the Spring container, ObjectPostProcessor is to solve the problem.
Once a bean is registered in the Spring container, we have a way to enhance the functionality of a bean or modify the properties of a bean.
For example, the authorization configuration code mentioned at the beginning.
|
|
Permission management itself is controlled by the FilterSecurityInterceptor
. The default FilterSecurityInterceptor
has already been created and I have no way to modify its properties, so what can I do? We can use the withObjectPostProcessor method to modify the relevant properties of the FilterSecurityInterceptor
.
One of the reasons why the above configuration works is because the FilterSecurityInterceptor
retraces the postProcess
method after it is successfully created. The property modification can be achieved here by overriding the postProcess method, and we can look at the method for configuring the FilterSecurityInterceptor
(AbstractInterceptUrlConfigurer#configure
).
|
|
As you can see, after the securityInterceptor object is created successfully, it will still go to the postProcess method.
Once you understand the above code, I’ll give you another example that you should be able to understand in a second.
|
|
Here, I take the configured UsernamePasswordAuthenticationFilter
out again and modify the username key (normally, you don’t need to go through all this trouble to modify the username key, this is mainly to show you the effect of ObjectPostProcessor
). After the modification, when the user logs in, the username is not username
but name
.
4. Summary
Well, if you have mastered the above usage, in the future in Spring Security, if you want to modify the properties of an object, but do not know where to start, then you may want to try withObjectPostProcessor!
Reference http://www.enmalvi.com/2021/06/23/springsecurity-objectpostprocessor/