I try to get bean, by using ClassPathXmlApplicationContext. But I receive: NoSuchBeanDefinitionException: No bean named 'newsController' is defined
ApplicationContext applicationContext = new
ClassPathXmlApplicationContext("classpath*:conf/Spring_Config.xml");
NewsController newsController = (NewsController)
applicationContext.getBean("newsController");
In xml:
<bean id="newsController" class="NewsController"/>
Add full path to the bean class tag
class=com.foo.NewsController
Related
I have a spring boot application, say A, which has a bean defined in xml:
<bean class="com.learning.MyBean" name="myBean">
<property name="maxAngle" value="360" ></property>
</bean>
Bean is:
public class MyBean {
#Value("${maxAngle}")
public void setMaxAngle(double maxAngle) {
....
}
}
When I run A independently, all is fine. But when I include it as dependency in another spring boot application, then I get error related to injection of maxAngle:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myBean': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'maxAngle' in value "${maxAngle}"
What can be the issue here?
#Value annotation is used to bind properties defined in application.properties or application.yaml.
Try adding maxAngle=360 to application.properties or application.yaml and remove it from bean XML defination
I have a large Spring Project, whose beans are mostly created via the #Component annotation on classes. I'm slowly tring to move the bean definition to the spring.xml config file.
I however, get a the following error whenever I try to autowire a bean created in the xml config file into a bean created via the #Component annotation.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ComponentBean' defined in class path resource [spring.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'xmlBean' of bean class [myproject.XmlBean]: Bean property 'xmlBean' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
In my spring.xml:
<bean id="xmlBean" class="myproject.XmlBean" />
Trying to autowire beans into #Component beans as follows does not work:
#Component
class ComponentBean {
#Autowired
private XmlBean xmlBean;
// Bean setters and getters
}
Is there a way by which I could marsh up the two, as I slowly port my bean definitions to the spring.xml config file.
I have Spring context with several beans, like:
<bean id="anyBean" class="com.my.app.AnyBean"
p:test_user="${any1}"
p:test_pass="${any2}">
</bean>
To resolve these placeholders (${any1} and ${any2}) I use:
<bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" p:location="my.properties" />
It works fine, but I need to define location of the 'my.properties' from 'main' method of the main class. Like this:
ApplicationContext context = new ClassPathXmlApplicationContext(my_xml_config.xml);
PropertyPlaceholderConfigurer ppc = context.getBean("propertyPlaceholderConfigurer", PropertyPlaceholderConfigurer.class);
Resource resource = context.getResource("path/to/my.properties");
ppc.setLocation(resource);
But when I try to launch it:
Exception in thread "main"
org.springframework.beans.factory.BeanDefinitionStoreException:
Invalid bean definition with name 'AnyBean' defined in class path
resource [my_xml_config.xml]: Could not resolve placeholder 'any1' in
string value "${any1}"
Could you hint is there any way to resolve this problem?
By the time you try to get a bean
PropertyPlaceholderConfigurer ppc = context.getBean("propertyPlaceholderConfigurer", PropertyPlaceholderConfigurer.class);
Spring has already tried to refresh your context and failed since the property isn't present. You need to prevent Spring from doing this by specifying it in the constructor
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"my_xml_config.xml"}, false);
Since the ApplicationContext is not refreshed, the PropertyPlaceholderConfigurer bean doesn't exist.
For this to work, you need to use a PropertySourcesPlaceholderConfigurer instead of a PropertyPlaceholderConfigurer (thanks M.Deinum). You can declare it in the XML in the same way as you did for the PropertyPlaceholderConfigurer bean, or use
<context:property-placeholder />
You need to take advantage of the fact that PropertySourcesPlaceholderConfigurer has its own locations, but also uses the PropertySource instances registered in the ApplicationContext's Environment.
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"your_config.xml"}, false);
// all sorts of constructors, many options for finding the resource
ResourcePropertySource properties = new ResourcePropertySource("path/to/my.properties");
context.getEnvironment().getPropertySources().addLast(properties);
context.refresh();
My XML configuration includes these bean definitions:
<bean id="abstractFormAction" class="staffing.server.action.form.AbstractFormAction" abstract="true" parent="baseAction">
<property name="volunteerSaver" ref="volunteerSaver"/>
<property name="emailSender" ref="emailSender"/>
<property name="closed" value="${form.closed}"/>
</bean>
<bean id="volunteerFormAction" class="staffing.server.action.form.VolunteerFormAction" parent="abstractFormAction">
<property name="captchaGenerator" ref="captcha"/>
</bean>
Indicating that VolunteerFormAction is a concrete implementation of AbstactFormAction, and will inherit the properties of AbstactFormAction.
In AbstractFormAction, I declare the properties like this:
#Autowired protected VolunteerSaver volunteerSaver;
#Autowired protected EmailSender emailSender;
#Autowired protected boolean closed;
I get the following exception when I try to deploy:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'volunteerFormAction': Injection of autowired
dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: protected boolean
staffing.server.action.form.AbstractFormAction.closed; nested
exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
matching bean of type [boolean] found for dependency: expected at
least 1 bean which qualifies as autowire candidate for this
dependency. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
It seems to be complaining that it cannot find a bean of byte boolean. But why would it want a bean when have defined property 'closed' by value, not by reference?
You need to use #Value annotation for passing values using property place holders. #Autowire expects a bean of the specified type to be present in the applicationContext.
If you are autowiring the values why are you passing the values int he bean definition? I think what you need is
<bean id="abstractFormAction" class="staffing.server.action.form.AbstractFormAction" abstract="true" parent="baseAction"><bean>
<bean id="volunteerFormAction" class="staffing.server.action.form.VolunteerFormAction" parent="abstractFormAction">
<property name="captchaGenerator" ref="captcha"/>
</bean>
and
#Autowired protected VolunteerSaver volunteerSaver;
#Autowired protected EmailSender emailSender;
#Value("#{form.closed}") protected boolean closed;
If you can use component-scan you need not even specify create the beans
You can add <context:component-scan base-package="<your base package>"/> to your context.xml file and add the annotation #Controller to your controller file
You shouldn't annotate closed with #Autowired.
#Autowired instructs Spring to look up a bean of the type of the autowired field (boolean) in your context, that's why it's complaining about "No matching bean of type [boolean]"
If you inject the value from xml config, there is no need for any annotation on that field.
Based on the code you've shown, it's likely that you have a problem in the way you're loading your Spring contexts. My guess is that you're incorrectly component-scanning your controllers in both the root web application context and in the child context where the controllers are supposed to live. That means there are two instances of this class being created, and only one of them is being configured via the XML. Spring is attempting to autowire the other instance and failing with the given error. You'll find descriptions of the problem and solution in several other SO answers, like these:
Declaring Spring Bean in Parent Context vs Child Context
Spring XML file configuration hierarchy help/explanation
Spring-MVC: What are a "context" and "namespace"?
If you give more detail about your config files and context configuration, someone might be able to point out exactly where you're going wrong.
My application context looks likt this,
<bean id="caseTxBo" class="gov.case.rcp.bo.impl.caseTxBoImpl" >
<property name="caseTxDao" ref="caseTxDao" />
</bean>
<bean id="caseTxDao" class="gov.case.rcp.dao.impl.caseTxDaoImpl" >
<property name="sessionFactory" ref="sessionFactory" />
Action class gets the context like this:
ServletContext context = request.getSession().getServletContext();
BeanFactory factory = WebApplicationContextUtils.
getRequiredWebApplicationContext(context);
CaseTxBOImpl caseTxBo = (
caseTxBoImpl) factory.getBean("caseTxBo");
List<caseTxPmt> errorVarList =
caseTxBo.getcaseTxDao().findAllcaseTx();
model.put("caseTxList", caseTxList);
BOImpl implements Dao and DAOImpl implements Dao:
DaoImpl has the implementation and returns caseTxList.
but I get a runTimeException as
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'caseTxBo' defined in ServletContext resource [/WEB-INF/classes/applicationContext.xml]: Cannot resolve reference to bean 'caseTxDao' while setting bean property 'caseTxDao'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'caseTxDao' defined in ServletContext resource [/WEB-INF/classes/applicationContext.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'sessionFactory' of bean class [gov.case.rcp.pp.dao.impl.CaseTxDaoImpl]: Bean property 'sessionFactory' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
follows:
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:275)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:104)
Where did i go wrong?
Bean property 'sessionFactory' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?
follows:
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:275)
The error message is pretty clear. Open your CaseTxDaoImpl and make sure there is a following method there:
public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
}
BTW this:
ServletContext context = request.getSession().getServletContext();
BeanFactory factory = WebApplicationContextUtils.
getRequiredWebApplicationContext(context);
factory.getBean("caseTxBo")
is pretty low-level usage of Spring and an anti-pattern. Are you using any web framework? Typically they integrate with Spring quite well.