I am modifying code that uses a Spring PropertyPlaceholderConfigurer in an application context file. The properties are successfully read and used in the application. However, if I follow the PropertyPlaceholderConfigurer declaration with an <import resource="classpath:/my/class/path/${my.file.name}" />, a "Could not resolve placeholder 'my.file.name'" error and a series of exceptions are thrown. Are properties immediately available after declaring the PropertyPlaceholderConfigurer? If not, at what point do they become available?
The import resources are resolved BEFORE the PropertyPlaceHolderConfigurer(a BeanFactoryPostProcessor) resolves the property place holders. You will have to put the resolved resource name in your imports.
Since PropertyPlaceHolderConfigurer is a BeanFactoryPostProcessor, it is called once the bean definitions have been loaded up from the Spring configuration files.
There's multiple passes done on a spring context file, so it's a question of at what pass are the properties available. Unfortunately, <import> tags are handled on an earlier pass than bean declarations (such as the one for your PropertyPlaceholderConfigurer), therefore it won't be available in the way you're trying to use it.
What you're (likely) trying to do is a common thing in Spring, with many various solutions. They often involve modifying your build to do the injection. Googling/Stack Overflowing for per-environment spring config should turn up something. I've read Spring 3.1 will provide a facility to allow per-environment configuration (so use "this" properties file if I'm doing a "test" build, this one if I'm doing a "dev" build etc.), but I don't know much about it at this point.
Related
We have a large Spring project with dependencies coming from many different internal libraries. We have a number of conflicts with the same bean being defined more than once.
We don't want to enable beans override configuration property. So, need to know who define these beans and where they are defined?
If you are using IntelliJ IDEA you can search for beans with Ctrl+Alt+Shift+N.
I want to know how to discover all qualifying beans that should be implemented when using some component together Spring.
For example, when using JPA and Spring Boot we need beans as like as sessionFactory and dataSource (Any more? I don't know, see It?).
Is there any official place where I can check the pre requisite list of beans?
I've made many searches through the official schemas and I couldn't find a pattern for bean dependencies.
After some time I've come into some steps that helped me and maybe help others. I'm answering this also because there are a lot of material related to Beans in XML files and in a Maven project, but if you try to create a XML free project, things become more rare when using Spring.
Notice: in deep Spring doesn't cares if the bean is an annotation or inside a XML. I preferred these configurations as a personal choice.
Some project details:
Gradle (project configurations are in application.properties file)
Java 8
Bean class(es) for src and for test. Note: You can use extends among them.
In case of doubt, https://start.spring.io/ an awesome way to create from nothing a spring project with your dependencies. Gradle format dependencies usually can be found at maven repository nearby the maven format.
Resolution:
Create a unit test (e.g JUnit) to just test your layer. For example mine was persistence layer.
Be careful to add each framework(that is going to be loaded by Spring) at once. Dealing with many unconfigured frameworks at same time would lead to caos since may be hard to figure out from where the Bean class should come from.
When the test fails look at his bottom of your console. Some exception will be thrown saying that a Bean with some name is missing. This are the guys you need.
Create a method typed with #Bean inside a class typed with #Configuration. This method must returns variable/object type complained in the exception message. Additional annotations maybe be required, for example, #EnableTransactionManagement for JPA beans.
Bonus:
Spring is deeply connected to IoC (dependency injection) and containers. Take a look at this contents because when you see that you realizes why to use Beans.
I have a spring based application that uses beans to describe the metadata of certain entities. As my application grows, the metadata also changes.
Upon a new release of my application, I want to sustain the old bean definition together with the new one and to make them available to the program.
My original idea was to add a new property to the bean definition called 'Version'. Its value will correspond correspond to a release version. Thus if I want to change the metadata definition of one of the entities, I copy paste the old definition, make the required changes (e.g. add a field) and update the version field.
In code I can easily filter the beans by their version.
The problem:
Naturally, Spring will not allow me to have two beans with the same id (it does not know that I actually can disambiguate by version). It seems that instead of adding a new property to the bean definition, I need to encode the version in its name.
Is this the proper way to do it in Spring (I did not find any OOTB support for this)? Are there any other patterns that solve this issue?
You can't have two beans of the same type and the same name at the same time. You could include a version suffix in the bean name, but this is likely to break some of your #Autowired injections.
Spring profiles (introduced in 3.1) are a way to quickly switch between alternative context configurations, but activating two of them at the same time may again lead to conflicts.
Let's say I am defining a custom aspect and to enable proxying I am using aop:aspectj-autoproxy. Now I am also importing another third-party spring context in the application that also happens to call aop:aspectj-autoproxy (ofcourse I won't know about it upfront unless I pore over the context xml contents extracted from the JAR). Potentially there can be many such contexts. Here I see that the beans matching the pointcut get proxied over and over i.e. proxy of a proxy. Is there a way that one can avoid such a proxy of a proxy? Also feel free to point out any anti-patterns that may be at play here.
Thanks in advance.
From Spring documentation:
http://static.springsource.org/spring/docs/3.0.6.RELEASE/spring-framework-reference/html/aop.html#aop-proxying
Note Multiple sections are collapsed into a single
unified auto-proxy creator at runtime, which applies the strongest
proxy settings that any of the sections (typically from
different XML bean definition files) specified. This also applies to
the tx:annotation-driven and aop:aspectj-autoproxy elements.
To be clear: using 'proxy-target-class="true"' on
, or
elements will force the use of CGLIB proxies for all three of them
I believe the problem mainly relates to
Now I am also importing another third-party spring context in the application that also happens to call aop:aspectj-autoproxy
Instead of directly importing the app ctx provided by 3rd party lib (which is, in most case, provided for ease of initial development or for small project), try to manage those 3rd party beans in your own app ctx, and make sure you do not have multiple aop:aspectj-autoproxy (There are lots of bean post-processor etc in spring that is not safe in multiple declaration.)
We can use both Spring config file OR a .properties file to store and retrieve some properties, like for a database connection. (db url, db password and etc)
We can also use Spring config file and a .properties file together, where we reference the property from a .property file (like in ant)
What would be the advantages or disadvantages for the following scenarios:
1 - Using only .properties file.
2 - Using only Spring config file.
3 - Using both together.
Would any of the scenarios be better when it comes to maintenance?
I need to choose between the three, and I would like to have a better judgement before I go with any of the option!
Thanks in advance!
- Ivar
Both together. Use a properties file that's externalizable from your project to configure Spring. Spring then configures your project. Mostly, you don't write code to read from properties files. Let Spring manage that and inject your objects with the appropriate values. Then you have appropriate dependency injection and the artifact you build isn't environment-specific.
Disadvantages:
How does your code know what file to load the properties from? Isn't that a property? It also violated dependency injection by having code go find a resource rather than passively accepting one.
Configuration is tightly coupled to your artifact and can't change between environments without rebuilding (BAD).
The way you seem to think of it, this combines the disadvantages of the other two, but if you do it the way I described, it eliminates those disadvantages, which is an advantage.