How to import Java-config class into XML-config so that both contexts have beans? - spring

I have a project where I need to bootstrap #Configuration java-config classes into the XML configuration.
To do that, I'm reading that I also need to include the following bean definition (along with the bean definitions of the classes annotated with #Configuration).
<bean class="org.springframework.config.java.process.ConfigurationPostProcessor" />
But, I end up receiving the following error:
Caused by: java.lang.ClassNotFoundException: org.springframework.config.java.process.ConfigurationPostProcessor
I have to assume I'm missing a jar somewhere, but my various web searches hasn't resulted in an answer yet. Any help would be greatly appreciated. Thanks.
EDIT: Evidently, I was reading old documentation, which is no longer current. Let me back up. My project contains older XML-based configuration. The newer code is all using 'Java-config'. With that said, the contexts are apparently completely separate. I'd like to 'import' a java-config class into the XML configuration, so that both contexts have those particular beans. Does anyone know how I can do that?

This actually ended up being fairly simple. To get a Java-config bean definition into the xml-config, simply define the Java-config class as a bean within the XML-config. There are no extra jars necessary.
#Configuration
public class SomeJavaConfig {
#bean
... [bean definition]
}
inside the XML-config, you define this class as a bean.
<!-- needed to pick up the annotated java-config -->
<context:annotation-config />
<!-- Importing java-config class, which are annotated with #Configuration -->
<bean name="SomeJavaConfig" class="[fully qualified path].SomeJavaConfig" />
The XML-config, which may be part of a different context, now has all the bean definitions defined within the JavaConfig class.
UPDATED - to included Alan Franzoni's comment below in the answer.

Alternatively to annotation-config you can use component-scan. Then you do not have to include the Configuration Bean in XML:
<context:component-scan base-package="[fully qualified package path]" />
See Difference between <context:annotation-config> vs <context:component-scan> for more details.

Should be in:
spring-javaconfig-<version>.jar

Related

Integrate XML based spring mvc with java config based spring security

I've already done a simple project on spring mvc framework with XML config file. Now I want to add spring security with java config file in that project. Is it possible to integrate. I've almost spend a whole day searching it on google. I've already read documentation but I didn't get any clue. Can anyone provide me good reference for it? Thanks in advance
You have 2 options depending on which is leading, the XML or Java version. Both of them are quite well documented in the Spring Reference Guide.
When using XML you can simply add the #Configuration annotated class as a bean to the XML configuration like any other bean.
<bean class="your.configuration.class.Here" />
You have to have <context:annoation-config /> to have the #Configuration class processed.
However if you already have <context:component-scan /> and the package(s) you are scanning already includes the package that contains the #Configuration class you don't need to do anything as it will be detected like any other #Component.
If you want you have your #Configuration class leading then you can simply import the XML configuration using #ImportResource.
#Configuration
#ImportResource("your-configuration-here.xml")
public class SecurityConfig {}
Either way will work, which depends on which you want to make the leading configuration standard.

Spring ConflictingBeanDefinitionException

I have ProjectA defining a MyService class.
ProjectA contains multiple concrete services, for example: SomeService.
Now I have ProjectB, which is a spring boot project, having ProjectA as dependency.
ProjectB may add some functions to SomeService by defining its own public class SomeService extends project.a.SomeService {...}. The beans are scanned via #ImportResource("applicationContext.xml").
applicationContext.xml:
<beans ...>
<context:component-scan base-package="project">
<context:include-filter type="assignable"
expression="project.a.MyService" />
</context:component-scan>
</beans>
Main problem is: This leads to ConflictingBeanDefinitionException:
Annotation-specified bean name 'someService' for bean class
[project.a.SomeService] conflicts with existing,
non-compatible bean definition of same name and class [project.b.SomeService]
Although the exception is really clear, I have no idea how to solve it. After my research I'm relativley sure setAllowBeanDefinitionOverriding(true) should solve my problem. Maybe I just do it at the wrong time, but it never helped (also I think true is the default value).
My attempt:
I tried to avoid all scanning and register my beans by myself as well:
GenericApplicationContext ctx = (GenericApplicationContext) SpringApplication.run(ProjectBApplication.class, args);
ctx.getBeanFactory().registerSingleton("someService", new project.b.SomeService());
...
I can filter MyServices specifically this way but now I'm running in autowiring problems using SomeService in other (following!) beans.
Maybe I'm just registering the someService bean wrong?
I've already read about BeanPostProcessors, but I did not get how they could help me and where to use them correctly.
Keep in mind: any solution will fit, no matter if filtering MyService's in code, in xml, just tell spring to overwrite beans with more specific ones or what ever.
I figured out I just registered the bean wrong. Using
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(service);
context.registerBeanDefinition(beanName, beanDefinition);
solved the autowireing problem and at the moment every thing works fine.

#Autowired in bean not in spring context

I am new to springs. Is there an alternative for autowired to be used in a ordinary java bean which is not present in spring context.
You can do so by using Spring #Configurable with some AspectJ magic.
If you need a detailed explanation, here is the link.
And here is a brief overview of how it can be achieved.
First you have some bean that you want injected somewhere:
#Component
public class InjectedClass {
// ...
}
Then, you have a class that is not spring-container managed, that you want to instantiate. You want autowiring to work with this class. You mark it as a #Configurable.
#Configurable
public class NonContainerManagedClass {
#Autowired
private InjectedClass injected;
// ...
}
Now you need to tell spring that you want this non-container managed autowiring to work. So you put the following in your spring configuration.
<context:load-time-weaver />
<context:spring-configured />
Now, since this kind of thing requires modification of the bytecodes of your #Configurable class. So you tell Tomcat to use a different classloader. You can do so by creating a context.xml in your application's META-INF diretory and putting the following in there.
<Context path="/youWebAppName">
<Loader loaderClass="org.springframework.instrument.classloading.tomcat.TomcatInstrumentableClassLoader"
useSystemClassLoaderAsParent="false"/>
</Context>
Now, Tomcat needs to find that classloader. You can ensure that by putting Spring's spring-tomcat-weaver.jar (probably named org.springframework.instrument.tomcat-<version>.jar) in your tomcat installation's lib directory, and voila, the aspectj magic starts working. For classes that are annotated with #Configurable annotation, the #Autowired dependencies are resolved automatically; even if the instances are created outside of the spring-container.
This is probably the only way to make that work with Spring, in a clean manner. Make sure that you have appropriate dependencies in your classpath.
Another way would be to use the full AspectJ functionality and providing custom aspects around all your constructors and handling the dependency-injection yourself.

Spring custom annotation - how to make it part of a library?

I've created a custom annotation (in Spring 3.05) that works great. I'd like to take that code and make it part of a library, packaged in a jar file, so I don't have to include my custom annotation code in each web app I write.
I'm unable to get Spring to act on the annotation, however. My library jar is in my web app's classpath and I tried scanning for it in applicationContext.xml:
<context:component-scan base-package="my.annotation.pkg" />
The field annotated with my custom annotation continues to be null.
Ideally I'd like to this to just work with a minimum of fuss and configuration, but so far I haven't had any success.
What part of Spring's wiring am I missing to get my custom annotation recognized when it's part of an external library?
Update
Here is how I "solved" it...just had to read a little more closely. In each context file (i.e. applicationContext.xml, dispatch-servlet.xml) I added the line:
<bean class="my.annotation.CustomInjector" />
...where my CustomInjector implements BeanPostProcessor. I based this on the code at this blog post: Implementing Seam style #Logger injection with Spring.
The author says I needed to do exactly what I did, so bad on me for not reading thoroughly. Why, though, is adding that bean definition required? Maybe Spring annotations are configured similarly under the hood - I just don't get why having the jar file on the classpath isn't enough.
Is your custom annotation annotated with the #Component annotation? From the Spring reference manual:
By default, classes annotated with #Component, #Repository, #Service, #Controller, or a custom annotation that itself is annotated with #Component are the only detected candidate components.
Alternatively, you could add a custom include-filter to the component-scan element in your XML configuration.

Autowire Annotation in Spring without using Component Scanning

Is it possible to autowire beans using the #Autowired annotation without using component scanning?
Yes. <context-component-scan .. /> is responsible for discovering beans annotated with #Component, #Controller, #Service, #Respository, etc.
In order to have annotations processed (#Autowired, #Resource, etc) you need <context:annotation-config />. Thus annotations are processed on beans that are listed in applicationContext.xml.
As far as I know, <context-component-scan .. /> activates <context:annotation-config /> automatically.
This is true for both spring 2.5 and 3.0. (thanks skaffman)
I have never tried without component-scanning enabled, however I can confirm that #Autowire annotations works in Spring 3.0.x even with beans that are defined via XML.
When using AnnotationConfigApplicationContext, annotation config processors are always registered, meaning that any attempt to disable them at the #ComponentScan level would be ignored.
If it is meant in the question that you should explicitly state:
- <context:component-scan ...> in your xml file(it enables <context:annotation-config />)
or
- #ComponentScan in your java config
Then the answer is - Yes, it is possible to enable component scanning without any of the stated above statements in your code or xml file.
Another approach is to use AnnotationConfigApplicationContext :
AnnotationConfigApplicationContext context=
new AnnotationConfigApplicationContext("org.example.your.package");
Where "org.example.your.package" is your package for stereotyped annotated classes: #Component, #Repository, #Service, etc.
AnnotationConfigApplicationContext will search for your beans in the base package and inner packages.
No, we must use #ComponentScan if you are using java based configuration
(or) <context-component-scan .. /> for xml based configuration.
Note: If you are not using any of the approaches no corresponding instances are created in AplicationContext.
and when you try to access a resource (http://localhost:8080/customers) will end up with
WARNING: No mapping found for HTTP request with URI [/customers] in
DispatcherServlet with name 'dispatcher

Resources