Best Practice Changing Spring Implementation Object in JUnit Test - java

I have a Spring-enabled JUnit Test. It loads my default applicationContext.
Now I want to replace a single bean for my test, i.e. entityManager with testEntityManager.
I can imagine three possible ways, which don't seem very elegant:
split the context (defaultContext, emContext) and override context file by test context file (emContext in test resources)
use factory and choose testEntityManager (in production code)
not to use Spring, but build the object hierarchy myself (least feasible solution)
Is there a best practice how to do it right?
Background to this question is: I really only want to replace the objects close at the boundary (DB, Webservices, etc)
Yours Sincerely
EDIT: I have solved it this way now:
I added a properties file to my classpath and test classpath and used a Spring alias in conjunction with a property placeholder.
This way I was able to wire my beans to a different implementation in the tests.

Spring allows you to override bean definitions, when you are loading contexts from multiple locations.
So you don't necessarily need to to split the context "/applicationContext.xml".
Instead have an additional application context for test "/applicationContext-test.xml", where you override the bean you need.
Then pull in both configurations and have the bean in the test configuration override the bean in the production configuration.
#ContextConfiguration({"/applicationContext.xml", "/applicationContext-test.xml"})

The best practise IMHO would be to use spring bean definition profiles. My documentation link will lead you to other readable resources. Google will also provide useful links like Gordon Dickens: Spring 3.1 Environment Profiles.

Related

How can I check all qualifying beans for Spring-boot or related frameworks

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.

How many ways are there to configure the Spring framework? What are the differences between them technically? (Not pros or cons..)

I am studying this book (which I would highly recommend), and I am confused about how the authors explain the way Spring framework can be configured.
You can see some code examples that are used in the book here. (They are available to anyone..) The code I am referring the will be the code from chapter 2, if you would like to take a look.
The book states that there are 3 ways to configure the Spring Container.
XML - based configuration
This will require an xml file that resembles something like this:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" ...>
<bean id="accountService" class="com.wiley.beginningspring.ch2.AccountServiceImpl">
<property name="accountDao" ref="accountDao"/>
</bean>
<bean id="accountDao" class="com.wiley.beginningspring.ch2.AccountDaoInMemoryImpl">
</bean>
</beans>
And then in order to bootstrap Spring, the code that will be used will be:
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/com/wiley/beginningspring/ch2/ch2-beans.xml");
I do not have any confusions at this moment.
Java Based Configuration
In this Configuration method, there will be a class for the configuration as follows:
#Configuration
public class Ch2BeanConfiguration {
#Bean
public AccountService accountService() {
AccountServiceImpl bean = new AccountServiceImpl();
bean.setAccountDao(accountDao());
return bean;
}
#Bean
public AccountDao accountDao() {
AccountDaoInMemoryImpl bean = new AccountDaoInMemoryImpl();
return bean;
}
}
and the code that is responsible for bootstrapping Spring looks like:
ApplicationContext applicationContext
= new AnnotationConfigApplicationContext(Ch2BeanConfiguration.class);
So up to here, all is clear for me. (Kind of..) I would also like to note that, here we actually have an Annotation which is called #Configuration...
Annotation Based Configuration
The last configuration method available, explained in the book is the Annotation Based Configuration.
There is an xml file just like we had in the XML-Based Configuration, however a much smaller one:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" ...>
<context:component-scan base-package="com.wiley.beginningspring.ch2"/>
</beans>
All the beans have Annotations such as:
#Component, #Service
etc..
And all the dependencies have the annotations:
#Autowired
so that beans can be injected.
The way Spring framework bootstrapped in this configuration method is as follows:
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("/ch2-beans.xml");
Here are my questions:
Why is the (so-called) Annotation Based Configuration actually using ClassPathXmlApplicationContext but not AnnotationConfigApplicationContext above? The latter seems much more appropriate to be used in a Configuration that has the words "Annotation Based" in it, isn 't it?
The Java Based Configuration explained in the book seems like what should be called Annotation Based Configuration.?
And the way Annotation Based Configuration explained in the book actually seems to me something like: XML-Based Configuration with Autowired beans. It does not even have the #Configuration annotation, which the "Java Based Configuration" has..
How many ways are there to configure Spring framework?
To avoid confusion, we should understand, that configuration definition and bean definition are two different things. There are three ways to define configuration, available in Spring 4 by default:
xml-based configuration, when you describe configuration in xml file;
java-based configuration, when configuration is Java class, marked with specific annotations;
groovy-based configuration, when configuration is file with Groovy code;
And there are two ways to add bean definitions into application:
configuration inside bean definition, when you add beans manually by declaration right in configuration.
In this case definition will be based on configuration type. For xml-config it will be <bean/> tag, for java-based config - method with #Bean annotation and beans {...} construction for Groovy.
annotation based bean definition, when you mark bean classes with specific annotations (like #Component, #Service, #Controller etc). This type of config uses classpath scanning.
In this case you have to specify directive for scanning classpath. For xml-config it will be <context:component-scan base-package="..."/>, for java-config - #ComponentScan annotation, for Groovy ctx.'component-scan'(...) invocation.
As you see, you can use configurations and bean definitions in different combinations.
Note, that if you use xml based config, you can choose approach to drive dependency injection: manually in xml, or by using annotations (#Autowire, #Required etc). In late case you have to define <context:annotation-config/>. But do not confuse bean definition and dependency injection control.
Now based on this point of view lets try to answer your questions:
Why is the (so-called) Annotation Based Configuration actually using
ClassPathXmlApplicationContext but not
AnnotationConfigApplicationContext above?
Book's author mixed up concepts. Actually, this is a xml-based configuration with annotation-based bean definition.
The Java Based Configuration explained in the book seems like what
should be called Annotation Based Configuration.?
You're right - Java based configuration really actively uses annotations, and could be called Annotation based. But annotation is a part of Java. In addition this is a traditional term, specified in documentation.
How many ways are there to configure Spring framework?
So, by default, we have three ways to describe configuration, and two ways to define beans. That turns six ways to configure Spring framework(by default). But, of course, all of this ways can be used in combination with each other.
The easiest way to understand this is to look into the long history of the framework how this was developed.
XML based configuration - this was there from the the beginning - version 1 - see javadoc for ClassPathXmlApplicationContext. This was around march 2004, the time of J2EE 1.4, which had HUGE xml configuration and Spring was big simplification (XML as well, but simpler). This uses XML for everything, including specifying autowiring, or what dependencies go where directly (your ref="accoundDao" example).
Annotation based configuration - in Spring 2.5 - this came as a reaction to Java EE 5, new anotations like #Autowired were introduced, there was still some context configuration in XML files - usually you would define which packages were to be scanned and rest of it was done automatically based on annotations - hence the name.
Java based configuration came with Spring 3, was improved in later versions. This is when AnnotationConfigApplicationContext and Configuration annotation were introduced - you could potentially drop XML entirely -> java based config. Although this became practical only later with version 4+, because of large number of xml helper tags for aop, jdbc etc.
Beside these 3 (2 actually as 1 and 2 use the same ApplicationContext class), are other ways to create a context:
have a look at all implementing classes of ApplicationContext interface
SpringJUnit4ClassRunner for junit tests
I bet there are other ways I am not aware of
At first, I want to give thanks Ken Bekov for his more resourceful answer. I have tried to improvise his answer so that anyone can learn more on this area.
Configuration Definition:
Spring 4 contains 3 ways to define its configuration. They are
Advantages of the annotation:
All the information is in a single file (no need to open two files to configure a given behavior)
When the class changes, no need to modify the xml file
Annoations often said to be more intuitive and robust when re-factoring application code. Also they benefit from a better IDE guidance like guise provides. But they mix application code with DI concerns. An application gets dependent on a framework. Clear separation is almost impossible. Annotations are also limited when describing different injection behaviour at the same place (constructor, field) dependent on other circumstances (e.g. robot legs problem). Moreover they don't allow to treat external classes (library code) like your own source. Therefore they are considered to run faster than XML.
Advantages of xml file:
Clear separation between the POJO and its behavior
When you do not know which POJO is responsible for the behavior, it is easier to find that POJO (searching in a subset of files rather than all the source code)
XML has the only benifit of a declarative style that is defined clearly separated from the application code itself. That stays independent from DI concerns. The downsides are verbosity, poor re-factoring robustness and a general runtime failure behaviour. There is just a general (XML) tool support with little benefit compared to IDE support for e.g. Java. Besides this XML comes with a performance overhead so it is usually slower than code solutions.
XML and Annotation Based Link:
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-annotation-config
Annotations vs XML, advantages and disadvantages
Java Dependency injection: XML or annotations
Spring annotation-based DI vs xml configuration?
Xml configuration versus Annotation based configuration
Groovy Based Link:
https://objectpartners.com/2016/01/12/using-groovy-based-spring-configuration/
http://blog.andresteingress.com/2014/02/14/grails-java-based-spring-config/
Bean Definition:
There are 2 ways to bean Definition:
Scanning classpath:
For xml-config it will be <context:component-scan base-package="..."/>, for java-config - #ComponentScan annotation, for Groovy ctx.'component-scan'(...) invocation.
Dependency Injection:
In xml based config, dependency injection can be done manually in xml, or by using annotations (#Autowire, #Required etc). On that case It is need to define <context:annotation-config/>
Question & Answer:
Q1: Why is the (so-called) Annotation Based Configuration actually using ClassPathXmlApplicationContext but not
AnnotationConfigApplicationContext above?
Ans: It is a xml-based configuration with annotation-based bean definition.
Application Context:
http://docs.spring.io/spring/docs/4.2.0.RELEASE/javadoc-api/org/springframework/context/ApplicationContext.html
AnnotationConfigApplicationContext:
1.AnnotationConfigApplicationContext and parent context
ClassPathXmlApplicationContext:
http://www.tutorialspoint.com/spring/spring_applicationcontext_container.htm
http://www.mkyong.com/spring3/spring-3-hello-world-example/
Q2: The Java Based Configuration explained in the book seems like what should be called Annotation Based Configuration.?
Ans: You're right on that case. Java based configuration uses annotations, and called annotation based configuration. But annotation is a single part of Java, nothing else.
But elaborately we need to understand how this hierarchy comes from xml to annotation based and at last groovy based?
An alternative to XML setups is provided by annotation-based configuration which rely on the bytecode metadata for wiring up components instead of angle-bracket declarations. Instead of using XML to describe a bean wiring, the developer moves the configuration into the component class itself by using annotations on the relevant class, method, or field declaration. As mentioned in the section called “Example: The RequiredAnnotationBeanPostProcessor”, using a BeanPostProcessor in conjunction with annotations is a common means of extending the Spring IoC container.
For example,
Spring 2.0 introduced the possibility of enforcing required properties with the #Required annotation.
Spring 2.5 made it possible to follow that same general approach to drive Spring’s dependency injection. Essentially, the#Autowired annotation provides the same capabilities as described in Section 6.4.5, “Autowiring collaborators” but with more fine-grained control and wider applicability.
Spring 2.5 also added support for JSR-250 annotations such as #PostConstruct, and #PreDestroy.
Spring 3.0 added support for JSR-330 (Dependency Injection for Java) annotations contained in the javax.inject package such as #Inject and #Named. Details about those annotations can be found in the relevant section.
Q3: How many ways are there to configure Spring framework?
Ans:
Theoretically, 3 ways to describe configuration, and 2 ways to define beans. It turns 3*2 = 6 ways to configure Spring framework (by default). All of this ways can be used in combination with each other.
But Actually, in a single word, we can configure spring framework by using XML or annotations.
Not exactly. There are either only two ways to configure the Spring framework. The two basic configuration tools for the Spring framework are:
XML files (outside java files)
Java (5 +) based annotations (inside java files)
Both of them can be used to:
configure an application context (meaning adding beans) - the constructors of concrete application contexts accept xml files, packages to scan, or directly named classes to load
bootstrap an application context in the case of a web application - using web.xml vs using a class implementing WebApplicationInitializer
And last but not least:
you can scan annotations from an xml configuration file by using <context:component-scan/>
you can load a xml file from an annotated configuration bean by using #import
The second way called Java Based Configuration in your book, is a particular annotation #Configuration. A class annotated with it will normally be a bean in the application context, but it can also declare other beans with the #Bean annotation on one method. That's the reason why those classes are generally loaded directly instead of bean scanned.
The third way called Annotation Based Configuration, is simply a mixing of the two modes, where you use xml configuration at higher level and just scan packages for additional beans.
TL/DR: there are only 2 ways to configure an application context in the spring framework:
xml configuration files
java annotations
and they can be mixed
but every single bean can be declared in 3 ways:
from a xml file
with a #Bean annotation inside a #Configuration annotated bean
directly with a #Component (or any of the specialized annotations #Controller, #Service, etc.)
Now for your precise questions:
Why is the (so-called) Annotation Based Configuration actually using ClassPathXmlApplicationContext but not AnnotationConfigApplicationContext above?
Because the ApplicationContext is first initialized form a xml configuration file. Package scanning occurs later with the help of <context:scan ...> tags. You use an AnnotationConfigApplicationContext if you directly initialize it from configuration classes or through package scanning.
The Java Based Configuration explained in the book seems like what should be called Annotation Based Configuration.?
They call it Java Based because it needs no xml so configuration only uses Java
I have not taken a look at the book, but your assumptions are actually correct.
To start a Spring application and have all the beans instantiated by the framework using XML configured beans, you must use a ClassPathXmlApplicationContext.
There are 2 ways to configure beans in Spring:
1) XML beans
2) Annotation approach
Basically, XML beans were used in Spring 2.5-3 and Annotations approach is used more in Spring 4.
#Bean // is a way to create a bean. It is the equalivant of the beans tag in XML.
#Configuration // is a way to tell the Spring container that this class is a list of configuration beans
Spring has 2 spring containers:
1) BeanFactory
2) ApplicationContext
A BeanFactory is the most simplest container and only accepts one config file. An ApplicationContext is the most advanced Spring container and is used in enterprise applications as it accepts an array of config files, has JNDI integration, EJB integration and supports internationalisation of messages.
I hope that helps.
Let me first show different in coding first:
XML: you have to register your spring bean inside xml context file using <bean/>
Java Configuration: you have to use #Configuration and #Bean to register your spring bean in context.
Annotation: by using #Component and its friends is actually common could be used with other 2 using:
in xml using <context:component-scan/>
in java config using #ComponentScan
Why used ClassPathXmlApplicationContextbecause he used xml to configure component scan but if he used #ComponentScan then will sure use AnnotationConfigApplicationContext
So for me I consider it as 2 ways to initialize spring context xml or java configuration and Annotation is option could be used by any one of them or not used at all.
The three ways to configure the spring framework are not at all meant to be mutually exclusive. Actually, my guess is that on average you will find at least two of them used together.
The annotation based configuration is the least likely to be used stand-alone, simply because it relies on metadata that is inherently scattered throughout the source code.
The AnnotationConfigApplicationContext can be used to fire up a pure annotation-based context, but you will need to pass in all your classes annotated as #Component or derivatives, rather than passing in a single (or a couple of) #Configuration-annotated class(es) -- which is usually not practical.
Although this is pretty much the same as statically listing the beans in XML or Java configuration, the fact that you'll need to do this in code when you build the application context itself makes it less useful, as you can't benefit of the various clever ways of automatically firing up an application context (in web contexts and so on).
That's why you will probably want to be able to have the full object graph metadata assembled in one go, and that can only be achieved with either XML or Java-based config, which rely on "centralized" metadata describing the whole object graph.
For both XML and Java-based approaches, this "centralized metadata" (<beans> or #Configuration) can be defined statically (with explicit <bean> or #Bean definitions) or dynamically (using <component-scan> or #ComponentScan). So it's reasonable to say that these two approaches are just different formats with pretty much the same capabilities which can both benefit of annotation-based config for gathering the "de-centralized" metadata.

JSR-299 (CDI) configuration at runtime

I need to configure different #Alternatives, #Decorators and #Injectors for different runtime environments (think testing, staging and production servers).
Right now I use maven to create three wars, and the only difference between those wars are in the beans.xml files. Is there a better way to do this? I do have #Alternative #Stereotypes for the different environments, but even then I need to alter beans.xml, and they don't work for #Decorators (or do they?)
Is it somehow possible to instruct CDI to ignore the values in beans.xml and use a custom configuration source? Because then I could for example read a system property or other environment variable.
The application exclusively runs in containers that use Weld, so a weld-specific solution would be ok.
I already tried to google this but can't seem to find good search terms, and I asked the Weld-Users-Forums, but to no avail. Someone over there suggested to write my own custom extension, but I can't find any API to actually change the container configuration at runtime.
I think it would be possible to have some sort of #ApplicationScoped configuration bean and inject that into all #Decorators which could then decide themselves whether they should be active or not and then in order to configure #Alternatives write #Produces methods for every interface with multiple implementations and inject the config bean there too.
But this seems to me like a lot of unnecessary work to essentially duplicate functionality already present in CDI?
edit
Ok, I realized I'm a bit stupid... of course it is possible to add stereotypes and inteceptors at runtime using the CDI extension API:
void beforeBeanDiscovery(#Observes BeforeBeanDiscovery bbd) {
bbd.addInterceptorBinding(...)
bbd.addStereotype(...)
}
But what I didn't find was an API to add a decorator. The only thing I found was to activate all #Decorators in the beans.xml, then observe
public <T> void processAnotated(#Observes ProcessAnnotatedType<T> event)
and call
event.veto()
if I don't want a #Decorator to be active.
You might want to take a look at JBoss Seam, specifically the Solder sub-project.
It allows dependency driven CDI resolution, so that certain beans are only available if other beans or resources are available. (Class A if "dataSource" is available, Class B if "entityManager" is available)
Since it's open source, you can also take a look at how they wired that together, and use that knowledge as a basis for writing your own extension if needed.
If you're using JSF, I would highly recommend using SEAM-JSF as well, as it gets rid of the clunkiness of having two injection frameworks (JSF DI/CDI) and allows CDI beans in JSF scopes.

Spring Test Configurations

I'm fairly new to Spring and my understanding is a bit scratchy so bear with me and word answers for an idiot.
I've started working on a relatively large, maven based project which has a load of (xml) spring configuration. For this we have a bunch of JUnit tests. At the moment spring configuration for the tests replaces the configuration for the core project modules, which is an issue because it means that if we make changes to the configuration of the main project then those changes aren't reflected in the test module and hence it's possible to get funny test results.
We are currently changing this structure so that the test module configuration overrides (rather than replaces) the main modules configuration. So we only have to override the particular beans we are interested in for each tests.
Is this the best way to do this? Are there alternative ways? Is it possible to fine tune this ever further so that you can override specific setters of a particular bean (rather than the entire bean) for tests?
Any advice is much appreciated.
You can split your main configuration in separate (logical) units and import them into your test configuration as needed.
Keep in mind that Spring 3.1 will introduce XML profiles. This is perfect for testing (with different enviroment specific configurations). It's not finally released yet but I would (and do) use the milestone in new projects.
Ow having to mess with the method to test it is a bit weird by it self in my opinion.
I would avoid that at all if possible, and use spring resources to help you, with dependency injection, different application-contexts for test and dev and mock frameworks you can test almost every thing I can think of.
Maybe you could try to use those.
An example, it's a bit hard to simulate an user security context, but with spring it becomes fairly easy, you just need to create an application-context.xml for the tests (and point to it) and assign a factory in it to create a Bean of Authentication type(it's an interface) and you can use easy mock to automate this bean responses.
But for that to work you have to build your code with that in mind so instead of calling SecurityContext.getContext.... you inject that Authentication Bean from the factory.
In your main configuration separate out all the environment dependent configuration (like datasource, jms connectionfactory etc) to a separate config file - (something like infrastructure-config.xml). The configuration that doesn't change across test & deploy goes into a different file - application-config.xml.
Now for the test only create a new version of the infrastructure config file - test-infrastructure-config.xml and use it with the application-config from the main.

EJB3 - obtaining bean via injection vs lookup - what are the differences, implications, gotchas?

There are two ways I know of to obtain an EJB instance:
dependency injection in servlets and EJBs via the #EJB annotation
JNDI lookup via Context.lookup anywhere
What are the differences, implications and gotchas in using either of these approaches? Are they the same? Is dependency injection faster than lookup? What about transaction handling and object lifecycle management?
Things I'm aware of include:
annotation
works with servlets and and EJBs only
convenient syntax
container independent
lookup
can instantiate different implementations of the EJB interface programatically at run time.
works from anywhere - e.g. POJOs.
depends on naming convention of container
Both achieve the same result. It's more a matter of coupling. With annotation, you achieve loose coupling and it's easier to mock and test. With direct lookup, you depend on the initial context which may be unconvenient sometimes.
IMHO lookup does not work everywhere. For instance in Glassfish, a lookup on a local EJB from a POJO will work only if has been "imported" previously with #EJBs(...) on one of the session beans that uses the POJO. See this discussion. You need to understand the difference between the local and global JNDI for that.
My advice would be: use annotation as much as possible. If a POJO need a reference to an EJB, pass it as parameter (e.g. in the constructor). That's called dependency inversion and is anyway a good practice.
Lookup depends on presence of JNDI implementation, that is, you have to configure JNDI implementation in order to run unit tests, then annotated fields can be configured manually.
I think it's kind a hard to mock annotated EJBs. When using lookup you are able to build some switch according to your environment (test -> LoginMockBean, production -> LoginBean).

Categories