How to write simple Service Bean xml in Java for JPA - spring

I can't find the syntax anywhere for this. I simply need to define 2 services in a new app. Previously they were defined in an xml file like:
<bean id="service1" class="somePackage.service.service1Impl" />
<bean id="service2" class="somePackage.service.service2Impl" />
I want to put these in to a java file. Is there some simple code I can write to convert these to Java? Thanks.

If you mean to convert their XML definition to Java definition, you will need to create a #Configuration class with #Bean annotated methods.
#Configuration
public class JavaConfig {
#Bean
public service1Impl service1() {
return new service1Impl();
}
}

I'm not sure if I asked this question correctly. I simply moved my xml to somewhere that the Class was looking.

Related

Wiring multiple beans with the same dependency via Spring Boot #Configuration

In older Spring MVC apps, where you'd specify application.xml and declare your app's beans so that Spring DI could instantiate them and wire them together, you might have something like this:
<bean id="chargeFactory" class="com.example.myapp.ChargeFactory" />
<bean id="paymentService" class="com.example.myapp.DefaultPaymentService">
<ref id="chargeFactory"/>
</bean>
<bean id="chargeAuditor" class="com.example.myapp.ChargeAuditor">
<ref id="chargeFactory"/>
</bean>
Which might help wire up the following code:
public interface PaymentService {
public void makePayment(Payment payment);
}
public class DefaultPaymentService implements PaymentService {
#Autowired
private ChargeFactory chargeFactory;
#Override
public void makePayment(Payment payment, String key) {
Charge charge = chargeFactory.createCharge(key);
charge.doCharge(payment);
}
}
public class ChargeAuditor {
#Autowired
private ChargeFactory chargeFactory;
public void auditAllCharges(String key) {
List<Charge> charges = chargeFactory.getAllCharges(key);
// blah whatever
}
}
How do you accomplish the same bean wiring in Spring Boot with the #Configuration class? For example:
#Configuration
public class MyAppInjector {
#Bean
public ChargeFactory chargeFactory() {
return new ChargeFactory();
}
#Bean
public PaymentService paymentService() {
return new DefaultPaymentService(chargeFactory());
}
#Bean
public ChargeAuditor chargeAuditor() {
return new ChargeAuditor(chargeFactory());
}
}
This might work but introduces some issues:
It would force me to have to write value constructors for all my classes, which goes against everything I see in literally every tutorial/article I've come across. Plus, if I had to do that, then there's no real value to #Autowired anyways...
At this point I'm essentially doing "DIY DI", which is OK, except I'm trying to deliberately use Spring DI :-)
Every time I call chargeFactory() I'm getting a new (prototype-style) ChargeFactory instance. Maybe I want a singleton. Using this approach I have to hand-roll my own singleton implementation.
Sure, I can do all of this, but I feel like I'm flagrantly misusing/misunderstanding how #Configuration is supposed to be used, because it seems like I'm introducing a whole lot of DIY/homegrown code to solve something Spring DI should be able to do for me.
How would I reference the chargeFactory bean and wire it into both the "provider methods" for the paymentService and chargeAuditor beans? Again, looking for the Java-based #Configuration solution instead of writing an XML document to define the wirings.
I found this article which seems to be the only tutorial/documentation (surprisingly) on wiring Spring Boot apps via #Configuration (which leads me to believe there might be other/better methods...), but it does not address:
How to specify singleton vs prototype bean instantiation patterns
If multiple instances of a bean-class exist, how do I specify which instance gets wired into which dependency?
How do I get around not defining value constructors for all my classes, and just let Spring/#Autowired inject fields automagically?
When you call chargeFactory() , spring won't create new instance everytime. Give it a try and see. Same object will be returned. Anyways
You can do something like this.
#Bean
public PaymentService paymentService(ChargeFactory chargeFactory) { return new DefaultPaymentService(chargeFactory); }

Do we need xml file for doing Spring configuration using Annotation?

I was reading about the ways of doing Spring configuration and came to know that there are three ways of doing the same viz:
1) Plain XML based.
2) Using annotation based.
3) Java Based Configuration.
I am comfortable with approach #1 viz. pure XML based.
Now, I tried to use the approach #2 viz. Using annotation based.
For example:
#Component("circleID")
public class Circle {
#Autowired
private Point point;
#Override
public String toString() {
return "Circle [point=" + point + "]";
}
}
I expected Using Annotation there won't be any need of any xml file, but we still to have XML file for the following.
<context:annotation-config/>
<context:component-scan base-package="com.example.point , com.example.shapes" />
So isn't using annotations approach we are providing information in parts, some by XML and some by Annotations?
I am not clear on this, can anyone help me in getting this doubt cleared?
XML is not required for Spring configuration. You can configure Spring with pure Java-based configuration (annotations).
For example, instead of using the XML you posted in your question you can create a class with #Configuration and #ComponentScan annotations:
#Configuration
#ComponentScan(basePackages = {"com.example.point", "com.example.shapes"})
public class MySpringConfig {
public static void main(String[] args) {
// Create Spring ApplicationContext from annotation config
ApplicationContext context =
new AnnotationConfigApplicationContext(MySpringConfig.class);
// ...
}
}
See Java-based container configuration in the Spring Framework reference documentation.

Spring Boot - bean definition

I'm looking into using Spring Boot for a new application but I'm having trouble figuring out the best approach to create the application beans.
At a high-level, this would be a web application that can have one or more beans of the same type - each with different property values. If I need to add a new bean of the same type, I should only have to configure it. Typically, if I was using Spring MVC, I would just define each bean in application context and load in the property values via a context file. Spring Boot prefers to do away with xml config, but I'm not sure how to translate the bean definitions into a Spring Boot solution. How do I still take advantage of IoC using Spring Boot.
Actually this has nothing to do with Spring Boot. As you mentioned, it supports both Java and XML bean configurations.
You can easily create multiple beans out of the same class using Java configuration.
XML config like:
<bean id="first" class="com.foo.MyClass" />
<bean id="second" class="com.foo.MyClass" />
translates into:
#Configuration
class MyConfiguration {
#Bean
MyClass first() {
return new MyClass();
}
#Bean
MyClass second() {
return new MyClass();
}
}
with Maciej Walkowiak's answer, it is also recomended to write it like this:
#Configuration
class MyConfiguration {
#Bean
#Qualifier("first")
MyClass first() {
return new MyClass();
}
#Bean
#Qualifier("second")
MyClass second() {
return new MyClass();
}
}
then later when you autowire you can use:
#Autowired
#Qualifier("second")
private MyClass myClass;

Setting #Autowired(required=false) globally during spring-boot test

I can't get the classic XML config
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor">
<property name="requiredParameterValue" value="false" />
</bean>
to work in spring-boot test. I've tried the equivalent Java Style
#Bean
public AutowiredAnnotationBeanPostProcessor annotation() {
AutowiredAnnotationBeanPostProcessor annotation = new AutowiredAnnotationBeanPostProcessor();
annotation.setRequiredParameterValue(false);
return annotation;
}
also to no avail.
I'm just trying to find a solution to cherry-pick the beans I need for unit testing.
Here's the code I'm using in the test itself:
#Rollback
#SpringApplicationConfiguration({PackageServiceTestConfiguration.class, DatabaseConfiguration.class, MybatisConfiguration.class})
#ActiveProfiles("test")
public class PackageServiceTest extends AbstractTransactionalTestNGSpringContextTests {...}
The content of PackageServiceTestConfiguration.class (Database and mybatis are the config part of the apps itself what I need to perform my test
#Configuration
#ComponentScan(basePackages = "com.project.api.permission.service",
includeFilters = #ComponentScan.Filter(Service.class))
#ImportResource("classpath:testContext.xml")
public class PackageServiceTestConfiguration {}
testContext.xml contains some test fixtures and the failing AutowiredAnnotationBeanPostProcessor configuration
Thanks to #ComponentScan I can filter down to the package for which component to configure, but this is still not as convenient as XML where I can actually define each of the bean I need with a one liner.
I still need to make the #Autowired component not required globally for test, and I can't find a way to do this.

Dynamically load spring bean properties from database or Java Objects )

I have a scenario where I need to load properties from database or java object into beans.
Consider the example:
<bean id="ConfigAsstDemoBeanParent" class="gps.springconfig.DemoClass" lazy-init="true">
<property name="demoValueFromBean" value="demoValue"></property>
<property name="demoValueForKeyFromProperties" value="${DEMO_KEY}"></property>
</bean>
and instead of the ${DEMO_KEY} property placeholder, which loads a value from the property file, I need to load a value from the database, which I retrieve using a stored procedure from a Java class.
Please suggest me a mechanism which I can leverage for the above scenario. Currently I am investigating extending SpringMain and/or PropertyPlaceholderConfigurer class and write my own custom BootStrapper.
Also please suggest hints on writing a BootStrapper for the above mentioned scenario.
One of the cases where Java configuration seems to be a great alternative:
#Configuration
public class Config {
#Resource
private DataSource dataSource;
#Bean
#Lazy
public DemoClass configAsstDemoBeanParent() {
DemoClass demo = new DemoClass();
demo.setDemoValueFromBean("demoValue");
demo.demoValueForKeyFromProperties( /* query the database here */);
return demo;
}
}
Note that you can inject DataSource (or JdbcTemplate) to your #Configuration class providing it was defined elsewhere.

Resources