#component spring annotation in wicket project? - java

I am very new to SO,I have working on the task where Load environment configurations and properties according to the environment like (dev,prod,test),I have been successfully achieved database configuration on DAO level by using <beans profile="profile.name">. In front end side I have to get properties file according to the environment so I have the different files. to call that i have tried the below code:
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
#Component
public class PropertiesUtility {
#Value("${mount.images.webpath}")
private String imagePath;
public String getImagePath() {
return imagePath;
}
public void setImagePath(String imagePath) {
this.imagePath = imagePath;
}
#Override
public String toString() {
return "PropertiesUtility{" +
"imagePath='" + imagePath + '\'' +
'}';
}
}
My context.xml configuration:
<context:annotation-config/>
<beans profile="dev">
<context:property-placeholder location="classpath:properties/pharmisa_web_conf.properties"
ignore-unresolvable="true" />
</beans>
<beans profile="test">
<context:property-placeholder location="classpath:properties/pharmisa_web_test_conf.properties"
ignore-unresolvable="true" />
</beans>
Calling PropertiesUtility:
public class URLUtility {
#SpringBean //even #Autowired also not working
static PropertiesUtility propertiesUtility;
public static String getCompanyLogoUrl(int id) {
StringBuffer sb = new StringBuffer(getImagePath());
boolean isEndWithSlash=PharmisaStringUtils.endsWith(getImagePath(),"/");
if (!isEndWithSlash){
sb.append("/");
}
sb.append(id);
sb.append("/");
return sb.toString();
}
private static final String getImagePath() {
return propertiesUtility.getImagePath().trim();
}
}
SpringJunitTest
Test working perfectly
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"classpath:spring/pharmisa_web-context.xml"})
#ActiveProfiles(profiles = "test")
public class CompanyServiceImplTest {
#Autowired
PropertiesUtility propertiUtility;
#Test
public void testAppProperties() {
System.out.println(propertiUtility.getImagePath());
}
}
When i tried to inject PropertiesUtility class in wicket page .I am not getting the value of the properties. because it is not injected. I have aware of #SpringBean in wicket but even though it is not working.
Is there anyway to get the value any alternative welcomes.
For your further i have followed the link
http://examples.javacodegeeks.com/enterprise-java/spring/load-environment-configurations-and-properties-with-spring-example/

URLUtility should be a Spring bean if you want #Component or #Autowire to work.
#SrpingBean works automatically only in Wicket components. In anything else you need to "ask for injection" explicitly with Injector.get().inject(this).

Related

Stuck converting Spring xml config to java config

I stuck converting my current test app in Spring from using XML configuration to using Java configuration...
I have the following files
App.java
package com.spring.ioc.DependencyInjection;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class App {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("app-config.xml");
Phone p = ctx.getBean("phone", Phone.class);
p.calling();
p.data();
}
}
Galaxy.java
package com.spring.ioc.DependencyInjection;
public class Galaxy implements Phone {
public void calling() {
System.out.println("Calling using Galaxy");
}
public void data() {
System.out.println("Browsing internet using Galaxy");
}
}
IPhone.java
package com.spring.ioc.DependencyInjection;
public class IPhone implements Phone {
public void calling() {
System.out.println("Calling using iPhone");
}
public void data() {
System.out.println("Browsing internet using iPhone");
}
}
Phone.java
package com.spring.ioc.DependencyInjection;
public interface Phone {
void calling();
void data();
}
app-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="phone" class="com.spring.ioc.DependencyInjection.IPhone"></bean>
</beans>
The code above allows me to demo how you can use XML & edit the text between 'IPhone' or 'Galaxy' by changing the bean name at the end of the fully qualified name
<bean id="phone" class="com.spring.ioc.DependencyInjection.IPhone"></bean>
or
<bean id="phone" class="com.spring.ioc.DependencyInjection.Galaxy"></bean>
How can do the same in using JavaConfig instead of XML config?
I know how to use Java configuration to just pull one bean but am lost how to set it up to alternate between two objects.
Can you please show me by modifying the code I provided or adding any other code needed?
I believe you can use
#Component("iphone")
public class IPhone {}
#Component("galaxy ")
public class Galaxy {}
and where you inject it,
#Autowired
#Qualifier(value = "iphone")
private Phone iPhone;
#Autowired
#Qualifier(value = "galaxy")
private Phone galaxy;

A Java config analog of XML configuration not working

TL/DR: The problem boils down to creating a custom Spring scope, injecting a prototype-like scoped bean into a singleton with proxyMode = ScopedProxyMode.TARGET_CLASS but still getting a singleton in the Java config version of the configuration (whereas it works fine with XML).
UPDATE: Problem solved, see answer.
I'm using jBehave to write BDD test scenarios for our Spring application. We recently thought that we need independence in executing test scenarios (meaning that test context has to be reset before each scenario) and found this article on the web that addresses exactly the issue we're dealing with.
The article advises creating a custom Spring Scenario scope, assigning it to the class that represents test context and injecting an AOP proxy instead of the context file.
I've coded everything in accordance with the article and it worked great, but the thing is we need it in terms of Java config, not XML, and when I converted all the changes to Java config, it stopped working - meaning the Map in StoryContext was not reset after each test scenario and contained values from the previous scenario.
My changes were as follows:
marked the ScenarioScope class with the #Component annotation:
#Component
public class ScenarioScope implements Scope {
private final ConcurrentMap<String, Object> cache = new ConcurrentHashMap<>();
#BeforeScenario
public void startScenario() {
cache.clear();
}
#Override
public Object get(String name, ObjectFactory<?> objectFactory) {
return cache.putIfAbsent(name, objectFactory.getObject());
}
#Override
public Object remove(String name) {
return cache.remove(name);
}
#Override
public void registerDestructionCallback(String name, Runnable callback) {
}
#Override
public Object resolveContextualObject(String key) {
return null;
}
#Override
public String getConversationId() {
return "scenario scope";
}
}
created a Spring configuration class to add the new scope:
#Configuration
public class SpringConfiguration {
#Bean
public static CustomScopeConfigurer scopeConfigurer() {
CustomScopeConfigurer configurer = new CustomScopeConfigurer();
configurer.addScope("scenario", new ScenarioScope());
return configurer;
}
}
annotated the StoryContext class with the #Component and #Scope annotations:
#Component
#Scope(value = "scenario", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class StoryContext {
private Map<String, Object> storyContext = new HashMap<>();
public void put(String key, Object value) {
storyContext.put(key,value);
}
public <T> T get(String key, Class<T> tClass) {
return (T) storyContext.get(key);
}
#PostConstruct
public void clearContext() {
storyContext.clear();
}
}
To my knowledge, the code above is analogous to the XML configuration, which was as follows:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation=" http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config />
<context:component-scan base-package="foo"/>
<bean id="scenarioScope" class="foo.ScenarioScope"/>
<bean class="foo.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="scenario" value-ref="scenarioScope"/>
</map>
</property>
</bean>
<bean id="storyContext" class="foo.StoryContext" scope="scenario">
<aop:scoped-proxy/>
</bean>
</beans>
Can anyone please point me to why the Java config is not working as expected? I've spent some time researching stackoverflow but the majority of similar questions is solved by adding proxyMode = ScopedProxyMode.TARGET_CLASS to the #Scope annotation, which I did.
UPDATE: So I tried to gradually move from XML to Java config by commenting / decommenting corresponding lines in the files and figured out that the problem is in this part of the code:
<bean class="foo.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="scenario" value-ref="scenarioScope"/>
</map>
</property>
</bean>
When I replace it with
#Configuration
public class SpringConfiguration {
#Bean
public static CustomScopeConfigurer scopeConfigurer() {
CustomScopeConfigurer configurer = new CustomScopeConfigurer();
configurer.addScope("scenario", new ScenarioScope());
return configurer;
}
}
the StoryContext bean becomes a singleton. I tried doing it another way through registering a custom BeanFactoryPostProcessor and using the registerScope() method as described here, but it didn't work either.
I've managed to solve the problem, and the solution was trivial: the ScenarioScope instance in the SpringConfiguration class has to be managed by the Spring container rather than be created via the new() operator:
#Configuration
public class SpringConfiguration {
#Bean
public static CustomScopeConfigurer scopeConfigurer(ScenarioScope scenarioScope) {
CustomScopeConfigurer configurer = new CustomScopeConfigurer();
configurer.addScope("scenario", scenarioScope);
return configurer;
}
}

Spring & JUnit: Configure using xml, not annotations

So, with Spring, I prefer xml over annotation. It's just a personal preference, I like having the xml docs unifying my spring config data.
Anyway, I'm working on a JUnit test case for database access. My first time using the spring-test library. I'm trying to use dependency injection to inject the StudentDao bean into this class below:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration ({"classpath:/test-context.xml"})
public class StudentDaoTest extends TestCase {
private StudentDao studentDao;
public StudentDao getStudentDao() {
return studentDao;
}
public void setStudentDao(StudentDao studentDao) {
this.studentDao = studentDao;
}
#Test
#Transactional
public void test(){
//This ends up printing null, identifying the problem
if(studentDao == null){
System.out.println("Null");
}
Student student = new Student();
student.setFirstName("First");
studentDao.insertStudent(student);
}
}
The thing is, as you can guess from the comment, is this isn't working. The test-context.xml file starts up, and the other context file it imports also starts up, as I can see from the log, so it's not that the program can't find the file. Somehow the xml doc that I have is just not configuring the bean properly.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<import resource="data-context.xml"/>
<bean id="studentDaoTest" class="io.craigmiller160.schedule.persist.StudentDaoTest">
<property name="studentDao" ref="studentDao"/>
</bean>
I discovered that if I used the #Autowired annotation on studentDao it does work. The thing is, I don't use annotations anywhere else in the program, and I want to maintain consistency. Honestly, I would prefer to avoid using #ContextConfiguration too, but I don't think I'll be able to do that.
So, I'm looking for help making this injection work with just xml. I know, I'm being picky, but I like my consistency, as I said.
Thanks in advance.
PS. the full filepath of the files is:
StudentDaoTest: src/test/java/io/myname/schedule/persist/StudentDaoTest
test-context.xml: src/test/resources/test-context.xml
If you don't want to use Spring annotations why use them ?
public class MyTest {
private ConfigurableApplicationContext context;
#Before
public void initApplicationContext() {
context = new ClassPathXmlApplicationContext("...");
}
#After
public void closeApplicationContext() {
if (context != null) {
context.close();
context = null;
}
}
#Test
public void test() {
context.getBean(Object.class);
// ...
}
}
Inject application context and work with it as you like:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration ({"classpath:/test-context.xml"})
public class StudentDaoTest extends TestCase {
#Autowired
private ApplicationContext ctx;
Actually the definition of the studentDaoTest bean has no effect on the test just because there is no such functional in the testing framework.

dependency Injection by annotation

I am a new user of spring. I am trying to achieve dependency injection by annotation. My
beans.xml is :-
<!-- Add your classes base package here -->
<context:component-scan base-package="com.springaction.chapter01"/>
<bean id="greeting" class="com.springaction.chapter01.GreetingImpl">
<property name="greeting">
<value>Naveen Jakad</value>
</property>
</bean>
bean which I want to inject is:-
package com.springaction.chapter01;
import org.springframework.stereotype.Service;
#Service
public class InjectBean {
private int id;
private String name;
public InjectBean() {
super();
}
//setter getter of above instance variables..
}
and the bean in which I want to inject above bean is :-
package com.springaction.chapter01;
import org.springframework.beans.factory.annotation.Autowired;
public class GreetingImpl implements Greeting {
private String greeting;
#Autowired
private InjectBean myBean;
public GreetingImpl() {
super();
}
public GreetingImpl(String greeting) {
super();
this.greeting = greeting;
}
public void setGreeting(String greeting) {
this.greeting = greeting;
}
#Override
public void sayGreeting() {
System.out.println(greeting + " " + myBean);
}
}
so when I test the above code by :-
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("config.xml"));
Greeting greeting = (Greeting)beanFactory.getBean("greeting");
greeting.sayGreeting();
I get the output "Naveen Jakad null", means in nutshell I am not able to achieve my target. So please help me out and let me know where I making mistake
if you want to inject by #Autowired you don't need to config it in xml :)
You need to set
<mvc:annotation-driven />
<context:component-scan base-package="com.your.base.package" />
That way spring will know to check for annotations
With Fixus solution you do not need the xml file where you define the "greeting" bean:
Just add:
#Component // or #Service if it's also a service
public class GreetingImpl implements Greeting {
This way you do not need to define your beans in the xml file.
If you use Junit test, you just inject the class to test (e.g "Greeting") in your MyJunitClass and have your context set to the one with the annotation-driven and component -scan definition.
You can see that doc to configure your JUnit tests:
http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/testing.html#integration-testing-annotations

How do I inject property from one bean into another in Spring 3.0?

In Spring 3.0.2, I am trying to inject the property of Bean A into another Bean B, but the Spring EL isn't working.
Bean A is being created manually in Java. Bean B is created through XML.
In this case Bean A is Potato and Bean B is Baby (both in package springinit).
Bean A (Potato):
public class Potato {
String potatoType;
public String getPotatoType() { return potatoType; }
public void setPotatoType(String potatoType) { this.potatoType = potatoType; }
#Override
public String toString() {
return "Potato{" + "potatoType=" + potatoType + '}';
}
}
Bean B (Baby):
public class Baby {
private String name;
private Potato potatoThing;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Potato getPotatoThing() { return potatoThing; }
public void setPotatoThing(Potato p) { this.potatoThing = p; }
#Override
public String toString() {
return "Baby{" + "name=" + name +
", potatoThing=" + potatoThing + '}';
}
}
In my Main class, I create a Potato and use it in the XML when trying to make a Baby
package springinit;
import static org.springframework.beans.factory.support.BeanDefinitionBuilder.genericBeanDefinition;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.core.io.ClassPathResource;
public class Main {
public static void main(String[] args) {
GenericApplicationContext ctx= new GenericApplicationContext();
// define java-based spring bean
ctx.registerBeanDefinition("myPotato",
genericBeanDefinition(Potato.class)
.addPropertyValue("potatoType", "spudzz")
.getBeanDefinition());
// read in XML-bean
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx);
xmlReader.loadBeanDefinitions(
new ClassPathResource("/resources/spring_init.xml"));
// print out results
System.out.format(
"Baby: %s%n%n" +
"Potato: %s%n",
ctx.getBean(Baby.class),
ctx.getBean(Potato.class)
);
}
}
Here's my spring_init.xml:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="myBaby" class="springinit.Baby" depends-on="myPotato">
<property name="name" value="#{myPotato.potatoType}" />
<property name="potatoThing">
<ref bean="myPotato" />
</property>
</bean>
</beans>
When I run main, I get this output:
Baby: Baby{name=#{myPotato.potatoType}, potatoThing=Potato{potatoType=spudzz}}
Potato: Potato{potatoType=spudzz}
I want the baby's name to be "spudzz", which is a property of myPotato. Why won't spring inject this value into the baby?
Thank you for reading. I hope it was clear enough.
Perhaps you need to call ctx.refresh() before getting beans.
From javadoc:
Typical usage is to register a variety of bean definitions via the BeanDefinitionRegistry interface and then call AbstractApplicationContext.refresh() to initialize those beans with application context semantics (handling ApplicationContextAware, auto-detecting BeanFactoryPostProcessors, etc).

Categories