I have some classes and i want declare these classes in bean xml file. I want to call methods from these classes with reflection. I mean i have two feature in bean tag, one 'id' and another 'class', I want when take id value to a methods in reflection, find class and call special method. anyway, i searched about java beans, reflection and etc but i cant use these and i want to see a simple tutorial because my knowledge is very basic and little :(
How can i use bean xml file in reflection for calling a method from special class that the class declare in bean file?
for using bean xml file, i should install spring framework? and where should i create xml file with beans tag?(i mean i should create this in special directory, like below src or below res...)
Thanks for advises
For spring web application,By default you can declare beans in
/WEB-INF/applicationContext.xml
You can also declare beans in someName.xml in separate folder inside /WEB-INF/ like
/WEB-INF/config/database.xml
which could be imported in /WEB-INF/applicationContext.xml or other like
<import resource="/WEB-INF/config/database.xml"/>
and register ApplicationContext using ContextLoaderListener in web.xml as follows:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
for more information look spring docummentation.
http://docs.spring.io/spring/docs/1.2.9/reference/beans.html
if you are doing android then there is spring-android library but it doesn't seems to help you.
Why should I use Spring Android?
you might need to write your bean declaration file as plain xml inside resource folder and
res/xml/
see:
http://developer.android.com/guide/topics/resources/providing-resources.html
additionally you will have to implement your logic reading beans from that xml file.
From the Spring page:
Features
A Rest Client for Android
Auth support for accessing secure APIs
Spring android does not have bean configuration. Why do you need it? What you want may be done with generics and reflection. Could you provide an example of why you want that?
Related
I spent few days fixing bugs in my Spring project. For really long time, my main problems in error log were:
Bean already exists
I have got two files:
WEB-INF/myproject-servlet.xml
WEB-INF/web.xml
in first one, I can put following input (let's assume I have got an application to manage animals in zoo):
<context:component-scan base-package="com.my.package.animals" />
with that (as well as I understand) we are enabling Spring beans auto-discovery. So now, when we run our application, Spring will take all classes from this package, later it will go through all config files in resources directory and will inititliaze all beans (placed in config files, which are associated with a given package).
The second one, web.xml includes lines like this
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/myproject-servlet.xml</param-value>
</context-param>
I can also put path to my config files, for instance:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:animals-config.xml</param-value>
</context-param>
So now, I have 'auto-detecting' in myproject-servlet.xml and I have got context-param in web.xml for the same objects.
My question is, is it possible, that errors "Bean already exists" are coming from this? I am almost sure that yes, I checked all beans ids and there is no duplicates.
So I have another question. What is a good approach of doing that? When I create new config file, where I should inform my application about that? In myproject-servlet.xml or web.xml. I really need to clean up my application and I will start with that.
I checked some examples and people rather do not put more than one <context-param> in web.xml file Simple example
Thank you in advance
Ok, I am really close to solve my problem.
Let's assume I have got two packages:
com.my.pckg.a
com.my.pckg.b
with classes
com.my.pckg.a.ClassA
com.my.pckg.b.ClassB
I added in myproject-servlet.xml following line:
<context:component-scan base-package="com.my.pckg.a" />
I have got a config file myconfig.xml and inside I have got beans based on classes ClassA and ClassB.
Let's say we have got beans with ids as follows:
ClassA: ida1, ida2
ClassB: idb1, idb2
So, I am running my jetty server and the question is:
Which beans will be initialized? I declared only package com.my.pckg.a, so from myconfig.xml, spring should load only ida1 and ida2 but this file includes also beans for another class.
So finally... ?
Finally, I suppose I find a problem. In web.xml file I have got a line:
<context:component-scan base-package="com.dirty.pckg" />
in this package I have got a class DirtyClass with #Controller annotation. One of the fields of this class is:
private static ApplicationContext context = new ClassPathXmlApplicationContext("dirty-config.xml");
So, when my application is getting up, Spring takes DirtyClass (because it has #) and maps it. Because os static modifier of context it triggers reading dirty-config.xml. That's way I could not understand why my code behaves in strange way.
The web.xml file is the configuration of your web application. It is not related to Spring.
The contextConfigLocation context-param is the one spring listener use to search for Spring configuration files. It is spring related.
You can have multiple spring configuration files that you register in your web.xml but these files must not define the same bean (bean id must be different). You can also have only one spring configuration file that will it self include other configuration files as described here : http://www.mkyong.com/spring/load-multiple-spring-bean-configuration-file/
Answer to the other question :
When you added the component scan, you ask spring to scan the package com.my.pckg.a for annotation like #Service, #Component, ... The component scan is not a filter for the rest of the configuration it is a configuration itself. So the fact that you added component scan, will not change the behaviour of myconfig.xml. Both ida1, ida2 and idb1, idb2 will be instanciated.
I don't really get what you are trying to accomplished with your configuration files. Maybe if you explain your needs, we could help you set up the right config for you.
web.xml is configuration file. It has classes(like listeners, filters,filter-mapping, servlet,servlet-mapping), resources and configuration(like context param, diplayname, error-page, session-config) of the application and how the web server uses them to handle web requests. When the web server receives a request for the application, it uses web.xml to map the URL of the request to the code that is supposed to handle the request.
Coming to what should be in web.xml and what should be in myproject-servlet.xml:
1)In Spring, ApplicationContext can be hierarchical. One ApplicationContext can have multiple child ApplicationContexts and can only have one parent. Beans in child ApplicationContext can access the beans in parent.
2)DispatcherServlet dispatches requests to handlers(controllers), with configurable handler mappings, view resolution configuration(what view template you use for the application for example jsp).
Keeping the two points in mind, our web.xml should be like:
<!--Root web application context(Parent context) - beans for service or persistence layer should be in this -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:service-layer-beans.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<!--DispatcherServlet loads its configuration into its own context(chile context) and refers Root web application context as a parent, so it have access to beans in parent context and can override it but not vice versa.-->
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/myproject-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
I am new to spring and currently struggling in understanding the settings required for using an existing spring project in my current project
I have a spring project which has all the service for communicating with the database and webservice.
I am writing a new application which neeeds to talk to the database and webservice.
I thought of re-using the existing implementation in the other project.
I included the project in the build path of the current project.
However I am getting dependency injection error.
Now I am kind of stuck to see what all the other files I need to have in my current project settings so that I can re-use the existing project.
Should I need to import the context file of the other project in to my current one? If so can someone point me to the documentation where I can refer for some guidance?
I'll give it a shot. Hope I can bring about clarity to your question... =D
When you say "I included the project in the build path of the current project.", I assumed you added a spring web project as a dependency to another spring web project. In summary, you can't add a spring web project as a dependency of another spring web project. Let's take some time to understand how you wire a bean to do injection in spring container first...
When you use spring framework, you will find a similar code in your web.xml like the following:
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
What you have just done is to use spring framework's servlet to handle every request URL that ends with .htm. Of course you may configure it otherwise.
You should also have another xml that contains all your bean tags. By default, it is spring-servlet.xml. In this spring-servlet.xml, you specify which bean shall be injected to which bean if you are going the xml configuration approach. If you are using annotation approach, you should have a tag to scan all your existing #Component (and its derived annotations) annotated classes, then use #Inject or #Autowired annotation to inject the declared instance(bean). For example:
<context:component-scan
base-package="org.companyname.webappname" />
<context:annotation-config />
So far, what I have been explaining is how to declare a bean in a spring container. An "injection" happens only when you declare a bean (to live in spring container when web server starts) in a spring container, and specify which class it should be injected into.
So now that you have two spring web projects (assumption), with two web.xml and two spring container, you will have a problem getting the base-project's spring container to find the dependent spring web project's packages/classes. I suggest you move all the classes in the dependent project into the base-project and only have one spring container (one web.xml).
Another way is to create a Java Library Project, place all your services, DAO and web services classes in it and build it as jar. In your base project, add the jar file (as dependencies) and either do a component-scan on the jar's package or declare it in xml with the jar's package. Either way, you should only have one spring container, one web.xml.
Hope I am not confusing you.
You got to understand how the IoC container work first. Here is where you need to read and digest how spring IoC works: http://docs.spring.io/spring/docs/3.0.x/reference/beans.html
Update: if you are doing a non web spring project, the concept of having only one spring container still stands. The solution of moving dependent project's classes to a jar file is still valid. Except that you don't configure spring via web.xml. =D
You need to import the file containing the bean definitions of the service layer(say, service-context.xml) into the new project.
It can be done as:
<import resource="classpath:service-context.xml"/>
It depends on how you have setup the project.
In general you would need to use
An example of this can be seen here (see the directions on how to include the project in your own application)
I have created a MessageBodyReader/MessageBodyWriter that needs to
read a configuration value. Ideally I'd like this to be held in the
web.xml as a context-param. Is there any way that a RESTEasy provider
can access context params? Is there any type that I can inject using
#Context that will allow me to get context-param values? I haven't
been able to find one.
Alternatively, is there a better way to provide configuration values
to a provider? I'd like to avoid having to use a system property.
In answer to my own question, one solution is to use Spring.
When RESTEasy beans are created via the the Spring context, one can easily provide configuration values in the application-context.xml. It's even possible to use context-param values from the web.xml using the ServletContextPropertyPlaceholderConfigurer.
consider a JSF web application with a managed bean FooBean.java. I've declared this "FooBean" in my faces-config.xml file. Now, if I want to add the Spring AOP advice for the methods of FooBean, how do I do that?
Should I add an applicationContext.xml file and declare the managed beans inside it?
or will it work even if I am not declaring the managed beans inside a Spring configuration file?
Note: I've created an Aspect bean and defined a point-cut like #Pointcut("within(dummy.web.reporting..*)") inside the aspect bean.
You can load a regular spring context xml file from within your web.xml like so:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/spring-context.xml</param-value>
</context-param>
You can then define your managed beans in here in the regualar spring way and you can still refer to these beans by id in your jsps.
You will also be able to use all the standard Spring AOP stuff within your spring-context.xml
I am using Spring AOP heavily in a Spring JSF application, I would rather suggest you to load your JSF beans via Spring container and also let Spring manage the Scope of the beans.
In such a scenario all beans would be loaded by Spring container thus it would become very easy to implement Spring AOP.
More info on such type of Spring-JSF integration
http://xebee.xebia.in/2011/10/31/spring-jsf-integration-made-easy-clean-using-spring-annotations/
I have a handful of projects that all use one project for the data model. Each of these projects has its own applicationContext.xml file with a bunch of repetitive data stuff within it.
I'd like to have a modelContext.xml file and another for my ui.xml, etc.
Can I do this?
From the Spring Docs (v 2.5.5 Section 3.2.2.1.):
It can often be useful to split up
container definitions into multiple
XML files. One way to then load an
application context which is
configured from all these XML
fragments is to use the application
context constructor which takes
multiple Resource locations. With a
bean factory, a bean definition reader
can be used multiple times to read
definitions from each file in turn.
Generally, the Spring team prefers the
above approach, since it keeps
container configuration files unaware
of the fact that they are being
combined with others. An alternate
approach is to use one or more
occurrences of the element
to load bean definitions from another
file (or files). Let's look at a
sample:
<import resource="services.xml"/>
<import resource="resources/messageSource.xml"/>
<import resource="/resources/themeSource.xml"/>
<bean id="bean1" class="..."/>
<bean id="bean2" class="..."/>
In this example, external bean
definitions are being loaded from 3
files, services.xml,
messageSource.xml, and
themeSource.xml. All location paths
are considered relative to the
definition file doing the importing,
so services.xml in this case must be
in the same directory or classpath
location as the file doing the
importing, while messageSource.xml and
themeSource.xml must be in a resources
location below the location of the
importing file. As you can see, a
leading slash is actually ignored, but
given that these are considered
relative paths, it is probably better
form not to use the slash at all. The
contents of the files being imported
must be valid XML bean definition
files according to the Spring Schema
or DTD, including the top level
element.
We do this in our projects at work, using the classpath* resource loader in Spring. For a certain app, all appcontext files containing the application id will be loaded:
classpath*:springconfig/spring-appname-*.xml
Yes, you can do this via the import element.
<import resource="services.xml"/>
Each element's resource attribute is a valid path (e.g. classpath:foo.xml)
Given what Nicholas pointed me to I found this in the docs. It allows me to pick at runtime the bean contexts I'm interested in.
GenericApplicationContext ctx = new GenericApplicationContext();
XmlBeanDefinitionReader xmlReader = new XmlBeanDefinitionReader(ctx);
xmlReader.loadBeanDefinitions(new ClassPathResource("modelContext.xml"));
xmlReader.loadBeanDefinitions(new ClassPathResource("uiContext.xml"));
ctx.refresh();
Here's what I've done for one of my projects. In your web.xml file, you can define the Spring bean files you want your application to use:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/modelContext.xml
/WEB-INF/ui.xml
</param-value>
</context-param>
If this isn't defined in your web.xml, it automatically looks for /WEB-INF/applicationContext.xml
Another thing to note is that although you can do this, if you aren't a big fan of XML you can do a lot of stuff in Spring 2.5 with annotations.
Yes, you can using the tag inside the "Master" bean file. But what about the why? Why not listing the files in the contextConfigLocation context param of the wab.xml or als locations array of the bean factory?
I think mutliple files are much easier to handle. You may choose only some of them for a test, simply add rename or remove a part of the application and you may boundle different applications with the same config files (a webapp and a commandline version with some overlapping bean definitions).