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
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
Two more important implementation classes, of which
AutowireBeanFactoryObjectPostProcessor is worth talking about, take a look at the definition of
The source code of
AutowireBeanFactoryObjectPostProcessor is well understood.
- First of all, when building the
AutowireCapableBeanFactoryobject is passed in, and if you have seen the Spring source code, you know that
AutowireCapableBeanFactorycan 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
2. Use cases in the framework
The next few examples of the framework directly
new object, we look at the role of
HttpSecurity initialization code (
WebSecurity initialization code (
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
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
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
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
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!