OK, I haven't used Spring in a while, so I'm a little rusty. Not sure if I missed something in all of this or not. My appContext.xml for Spring states that 'no setter is found for property testBean in class com.ztp.spring.injection.TestBean.
Here is the appContext.xml file:
<bean id="myTestBean" class="com.ztp.spring.injection.TestBean" />
<bean id="myTestClass" class="com.ztp.spring.injection.TestClass">
<property name="testBean" ref="myTestBean" />
</bean>
and here is the TestClass.java file in its entirety:
public class TestClass {
TestBean testBean;
public void setTestClass(TestBean testBean) {
this.testBean = testBean;
}
public void fillBean() {
testBean.setId(5);
testBean.setTestAnimal("sheltie");
}
}
I have another program that I worked on months ago, and its the same logic-wise, and it works. So I'm not sure what I'm missing.
If its already been answer or you need more info, just say so, I'd like to figure this out.
Thank you in advance.
Typo in the method name. What you meant is this:
public void setTestBean(TestBean testBean) {
this.testBean = testBean;
}
You had setTestClass. This would violate the JavaBean conventions.
The method name should match the property name for the bean:
public void setTestBean(TestBean testBean) {
Related
I am new to Java. I have below java class:-
#WebService
#SOAPBinding(style = SOAPBinding.Style.RPC, use = SOAPBinding.Use.LITERAL)
public class ABC extends AbstractWebService {
protected ClassNameForService classNameForService;
public void init() {
}
#WebMethod
#Path("/test")
#Produces("text/plain")
#GET
/**
*
* #return String
*/
public String test(
#WebParam(partName = "sessionID")
#QueryParam("sessionID") String sessionID
) throws UserNotDefinedException
{
// does something here
}
}
and below is my spring configuration file
<bean id=”org.testproject.webservices.ABC class=”org.testproject.webservices.ABC init-method=”init” parent=”org.testproject.webservices.AbstractWebService”>
<property name=classNameForService ref=”org.testproject.service.gb.ClassNameForService/>
</bean>
So do we need init-method=”init” here? Can I remove init-method=”init” from configuration as well as init method from class, Is it a standard practice?
You do NOT have to specify an init method (or destroy method for that matter). I think it's worth noting that you ask if it's standard practice, I believe the standard practice has moved away from the XML configuration to an annotation-driven approach but for the purpose of your question, it is standard practice to not include an init method when it is not needed.
The init-method is akin to adding a #PostContstruct annotated method on annotation declared beans.
I have the following bean:
package com.test;
#Component
public class Sample{
String modified = null;
#Value("${url}")
private String url;
public Sample(){
System.out.println(url );
if(baseUrl.equals(""){
throw new RuntimeException("missing");
}
else{
modified = "test"+url;
}
}
}
I have added:
<context:annotation-config />
<context:property-placeholder location="classpath:test.properties"/> & <context:component-scan base-package="com.test"/>
and trying to access above "modified" field as below
<bean id="url" class="java.lang.String">
<constructor-arg value="#{sample.modified}" />
</bean>
in my application context. But I keep getting the following error:
Field or property 'sample' cannot be found on object of type 'org.springframework.beans.factory.config.BeanExpressionContext'
Not sure why i get this error?
When Spring creates the object it uses the default constructor. It can't set the property until after it constructs it. Instead of what you have, try this to see if the value is being set.
#PostConstruct
public void init(){
System.out.println(url );
if(baseUrl.equals(""){
throw new RuntimeException("missing");
}
}
JustinKSU's answer is right. You have another option: inject value via constructor using #Autowired:
#Component
public class Sample {
#Autowired
public Sample(#Value("${url}") String url) {
System.out.println(url);
if(url.equals("") {
throw new RuntimeException("missing");
}
}
}
I have an application made up of 2 projects - UI and data. In the Data project, I have added a spring bean to the xml application context:
<bean id="mail-notification-service" class="com.test.DefaultEmailNotificationManager">
</bean>
This manager sends out notifications on request, and the parameters use a simple enum and a parameters object (both of which use classes only in the data project) to select an IEmailGenerator and use it to send the emails.
The manager is defined something like:
public class DefaultEmailNotificationManager implements IEmailNotificationManager {
public MailResult sendEmail( EmailType type ) { .. }
public void register( IEmailGenerator generator ) { .. }
}
public interface IEmailGenerator {
public EmailType getType();
}
Trouble is, the generators are defined in the UI project, so they can do things like get hold of wicket page classes, the request cycle, and application resources. Thus I can't add them to the bean in the data projects' applicationContext so that other modules in both the data and UI projects can use them.
Is there any way in the applicationContext of the UI project to do something like:
<bean id="exclusionNotifier" class="com.test.ui.ExclusionEmailNotifier"/>
<bean id="modificationNotifier" class="com.test.ui.ModificationEmailNotifier"/>
<call-method bean-ref="mail-notification-service" method="register">
<param name="generatorImplementation", ref="exclusionNotifier"/>
</call-method>
<call-method bean-ref="mail-notification-service" method="register">
<param name="generatorImplementation", ref="modificationNotifier"/>
</call-method>
I can manually tie the beans together in the WicketApplication.init method but would prefer something more elegant. Has anyone done anything like this?
Using Spring 4.1.4
Thanks in advance.
Inject generators into mail-notification-service bean (e.g. using autowire="byType") and register them right after bean construction using init-method (see Initialization callbacks in Spring docs)
public class DefaultEmailNotificationManager implements IEmailNotificationManager {
private Collection<IEmailGenerator> generators;
public void init() {
for( IEmailGenerator g : generators ) {
register(g);
}
}
public void setGenerators( Collection<IEmailGenerator> generators ) {
this.generators = generators;
}
public MailResult sendEmail( EmailType type ) { .. }
private void register( IEmailGenerator generator ) { .. }
}
data's applicationContext:
<bean id="mail-notification-service"
class="com.test.DefaultEmailNotificationManager"
init-method="init"
autowire="byType" />
UI's applicationContext:
<bean id="exclusionNotifier" class="com.test.ui.ExclusionEmailNotifier"/>
<bean id="modificationNotifier" class="com.test.ui.ModificationEmailNotifier"/>
I think the issue is pretty common, but for some reason I cannot manage to fix this.
This is the error I am getting:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'reverseController' defined in ServletContext resource [/WEB-INF/app-servlet.xml]: Initialization of bean failed; nested exception is java.lang.IllegalArgumentException: Validator [FormValidator#6b3ded0d] does not support command class [ReverseString]
This is the supports method in my FormValidator class:
public boolean supports(Class clazz) {
return ReverseController.class.isAssignableFrom(clazz);
}
This is the bean definition on my app-servlet.xml:
<bean id="reverseController" class="ReverseController">
<property name="commandName"><value>reverseString</value></property>
<property name="commandClass"><value>ReverseString</value></property>
<property name="formView"><value>reverse</value></property>
<property name="successView"><value>reverseResult</value></property>
<property name="validator"><bean class="FormValidator" /></property>
And finally, this is the main part of my ReverseController:
#Service
public class ReverseController extends SimpleFormController {
public ReverseController() {
//setCommandClass(ReverseString.class);
//setCommandName("reverseString");
}
private ReverseString reverseStringMaster;
#Autowired
public void setWriter(ReverseString reverseStringMaster) {
this.reverseStringMaster = reverseStringMaster;
}
protected ModelAndView onSubmit(HttpServletRequest request,
HttpServletResponse response, Object command, BindException errors) {
ReverseString revString = (ReverseString) command;
return new ModelAndView(getSuccessView(),"reversedString", revString);
}
public void init() {
System.out.println("Done");
}
}
Any idea what might be causing that issue?
It's an instance of the command class that gets validated on each request - as this gets populated with form data. The controller itself is not validated.
So the supports() method in your FormValidator should actually read:
public boolean supports(Class clazz) {
return ReverseString.class.isAssignableFrom(clazz);
}
Did you add getters and setters for this commandClass variable as well as well? If so, you probably need to remove the #spring.validator type="required" from the setter method method.
Try this code for your app-servlet.xml
1.Define your controller like this.
2.then use reverseController to call ReverseController class method.
<managed-bean>
<managed-bean-name>reverseController</managed-bean-name>
<managed-bean-class>com.action.ReverseController</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
For example, I have a class
public class Car{
private Motor motor;
public void setMotor(Motor motor){
this.motor = motor;
}
}
My bean looks like
<bean id="car" class="Car">
<property name="motor" ref="${motorProvider.getAvailableMotor()}"/>
</bean>
This method: motorProvider.getAvailableMotor() returns a bean name(string), of which motor I should use.
But there can be a situation when such bean(with such name) is not created. How can I check it?
There are several patterns how to do this. Here is one I often use:
public class Car{
private Motor motor;
#Autowired
private ApplicationContext applicationContext;
#PostConstruct
public void init() {
try {
motor = applicationContext.getBean( Motor.class );
} catch( NoSuchBeanDefinitionException e ) {
motor = new DefaultMotor();
}
}
}
Note you could also call applicationContext.containsBeanDefinition(name) but that would search your context twice (once in containsBeanDefinition() and then second time when you call getBean()) so catching the exception is usually faster.
Since we catch a specific exception that says "bean doesn't exist", using if/else has almost no advantage anymore.
SPeL; something like:
<property name="motor" value="#(if(${motorProvider} != null) ${motorProvider.getAvailableMotor()})"/>
I think it was discussed also here: Spring - set a property only if the value is not null . As they said before for more information see: http://static.springsource.org/spring/docs/3.0.5.RELEASE/reference/expressions.html