Getting access to a spring bean from a webservice? - spring

I have created a cxf webservice within my cxf.xml file I have the following tag.
bean id="videoStatsTable" class="com.company.auth.dataobjects.VideoStatsTable"
From what I understand Spring should create this object for me. The problem is I'm not sure how to get access to it. It seems as if I need the servletContext but as I'm in not in a servlet im in a WS im not sure how to do this?
W

Spring has a simplifed way of declaring web services (wiht cxf).
in your applicationContext.xml add xmlns:jaxws="http://cxf.apache.org/jaxws" to your root tag (<beans>) and
http://cxf.apache.org/core
http://cxf.apache.org/schemas/core.xsd
http://cxf.apache.org/jaxws
http://cxf.apache.org/schemas/jaxws.xsd
to your schemaLocation
Then add:
<!-- Loading CXF modules -->
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
And finally declare your WebService implementation:
<jaxws:endpoint id="MyWebService" implementor="#MyWebServiceImpl"
address="/myWebServiceAddress" />
where #MyWebServiceImpl is the ID of your bean. You can freely inject any other spring dependencies into that bean.
Then the web service will be accessible through http://yourhost/cxfuri/myWebServiceAddress (where cxfuri is the mapping of your CXF Servlet)

Related

Why we use factory-method="aspectOf" in aspect configuration

I found some code in my project.By seeing that i am confused how it scanning the package.we are not mentioning aspect package com.abc.b any where.I have few question
Why aop:aspectj-autoproxy is commentout in xml file?
why is used ?
How com.abc.b package is scanned by spring or there is no need of it or It has link from 'factory-method="aspectOf"'
serviceContext.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"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:cxf="http://cxf.apache.org/core"
xsi:schemaLocation="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
http://cxf.apache.org/core http://cxf.apache.org/schemas/core.xsd" default-lazy-init="true">
<import resource="classpath:META-INF/cxf/cxf.xml" />
<import resource="classpath:META-INF/cxf/cxf-extension-soap.xml" />
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<!-- <aop:aspectj-autoproxy /> -->
<!-- Enable message logging using the CXF logging feature -->
<cxf:bus>
<!-- <cxf:features>
<cxf:logging/>
</cxf:features> -->
<cxf:inFaultInterceptors>
<bean class="com.flipswap.interceptor.cxf.SafeLoggingInFaultInterceptor"/>
</cxf:inFaultInterceptors>
</cxf:bus>
<context:component-scan base-package="com.abc.service.impl,">
<context:exclude-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/>
</context:component-scan>
<bean id="eSSyncAspect" class="com.abc.b.ES" factory-method="aspectOf"/>
.
.
.
ES.java
package com.abc.b;
#Aspect
public class ES{
// some code
}
Unless you specify a custom instantiation model, aspects are by default singletons. That means - in case your code is properly woven -, that you can access the singleton instance of the aspect with AspectName.aspectOf().
In order for your classes to be woven by the AspectJ weaver, you need to either use compile-time/build-time weaving or load-time weaving.
In your spring configuration you are telling Spring to configure your aspect as a spring bean by telling how to access the singleton instance (through the static 'factory' method aspectOf). Spring will do the usual configuration (autowiring and any configured post-processors) on the singleton aspect instance.
aop:aspectj-autoproxy is commented out in your configuration because that would conflict with native aspectj support, as it would enable Spring AOP's dynamic proxy based AOP solution, which is very limited compared to native aspectj, and has a different mechanism to configure aspect beans than the one used in your configuration, namely through the static factory method AspectName.aspectOf().
In most cases, AspectJ aspects are singletons, with one instance per class loader. This single instance is responsible for advising multiple object instances.
A Spring IoC container cannot instantiate an aspect, as aspects don't have callable constructors. But it can obtain a reference to an aspect using the static aspectOf() method that AspectJ defines for all aspects, and it can inject dependencies into that aspect.
7.2.1.1. Example
Consider a security aspect, which depends on a security manager. This aspects applies to all changes in the value of the balance instance variable in the Account class. (We couldn't do this in the same way using Spring AOP.)
The AspectJ code for the aspect (one of the Spring/AspectJ samples), is shown below. Note that the dependency on the SecurityManager interface is expressed in a JavaBean property:
public aspect BalanceChangeSecurityAspect {
private SecurityManager securityManager;
public void setSecurityManager(SecurityManager securityManager) {
this.securityManager = securityManager;
}
private pointcut balanceChanged() :
set(int Account.balance);
before() : balanceChanged() {
this.securityManager.checkAuthorizedToModify();
}
We configure this aspect in the same way as an ordinary class. Note that the way in which we set the property reference is identical. Note that we must use the factory-method attribute to specify that we want the aspect "created" using the aspectOf() static method. In fact, this is locating, rather than, creating, the aspect, but the Spring container doesn't care:
<bean id="securityAspect"
class="org.springframework.samples.aspectj.bank.BalanceChangeSecurityAspect"
factory-method="aspectOf">
<property name="securityManager" ref="securityManager"/>
</bean>We don't need to do anything in Spring configuration to target this aspect. It contains the pointcut information in AspectJ code that controls where it applies. Thus it can apply even to objects not managed by the Spring IoC container.

Apache Camel integration with Activiti6 beta4

I'm trying to use Camel with Activiti6 beta4 using only the UI (activiti-app).
But in the log of the execution of my process model I get the error:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'myContext' is defined
It seems that the UI is unable to find my applicationContext.xml and/or "myContext" (the camel context inside applicationContext.xml).
My applicationContext.xml is in the /WEB-INF and has this content:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:camel="http://camel.apache.org/schema/spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<camelContext id="myContext" xmlns="http://camel.apache.org/schema/spring">
<route>
:::::::MY ROUTE::::::
</route>
</camelContext>
</beans>
Would anyone tell me what is missing?
The name and location of "applicationContext.xml" are correct?
TIA,
Wanderlan
I can't speak to using Activiti 6 beta with Camel, but I have it working on th 5.x engine and Activiti Enterprise Edition (with some hacking).
The default Camel Context that is installed is called camelContext, I see you have declared a Camel context called myContext. For some reason that bean has not instantiated or cannot be found.
Try using he default id of camelContext and see if your behavior changes.
Greg

Spring Lazy-init not working with #Resource injection

I have an interface with real and mock implementation. for obvious reasons the mock implementation is not in the production classpath.
I inject the bean using:
#Resource (name="${myClient}")
I am using Spring MVC and injecting this into a #Controller.
In external configuration I set the actual bean name to use and bind it to 'myClient' parameter. The binding works and it tries to load the real implementation but also fails on ClassNotFound on my mock although marked as lazy-init=true.
I am using Spring 4.0.0.
I know this is expected when suing #Autowire, but with #Resource I don't expect it to try and instantiate all beans in spring xml.
Any ideas wha't going on?
Here is the stack trace:
Caused by: org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [MyMock] for bean with name 'myClientMock' defined in URL [file:/C:/myProject/target/classes/META-INF/springContext.xml]; nested exception is java.lang.ClassNotFoundException: MyMock1
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveBeanClass(AbstractBeanFactory.java:1327)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:594)
at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1396)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doGetBeanNamesForType(DefaultListableBeanFactory.java:382)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:361)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanNamesForType(DefaultListableBeanFactory.java:347)
at org.springframework.context.support.AbstractApplicationContext.getBeanNamesForType(AbstractApplicationContext.java:1051)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.initHandlerMethods(AbstractHandlerMethodMapping.java:105)
at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.afterPropertiesSet(AbstractHandlerMethodMapping.java:89)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping.afterPropertiesSet(RequestMappingHandlerMapping.java:163)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1612)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1549)
I dont know if you´re using Spring profiles, but it´s what we use here to initialize different beans per environment.
From Tomcat we spcecify which profile use, and in Spring we have configure something like this.
<beans profile="deployed-local">
<util:properties id="propertyConfigurer" location="classpath:app.deployed-performance.properties"/>
<context:property-placeholder location="classpath:app.deployed-performance.properties,classpath:app.constants.properties"/>
<import resource="spring/jdbc-config-test.xml"/>
<import resource="spring/contacts-config-deployed.xml"/>
<import resource="spring/security-config-local.xml"/>
<import resource="spring/clamAV-service.xml"/>
<import resource="spring/document-service.xml"/>
</beans>
<beans profile="deployed-prod">
<import resource="spring/jdbc-config.xml"/>
<import resource="spring/contacts-config-deployed.xml"/>
<import resource="spring/security-config.xml"/>
<import resource="spring/clamAV-service.xml"/>
<import resource="spring/document-service.xml"/>
</beans>

Spring MVC 2.5 Using a mix of annotations & XML configuration but xml gets ignored

In my Spring MVC webapplication I want to mix xml based configuration with annotations:
I use annotations like #Controller, #RequestMapping("bla.htm"), #RequestParam etc. to resolve HttpRequests to Controller Methods. Therefore I added
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
<context:component-scan base-package="somePackage.controller"/>
to my dispatcher-servlet.xml.
But my controllers have attributes. Those attributes could be injected via #AutoWired annotation. But I also have do define Scopes. So i would have two annotations per attribute, which makes the code bad readable. So I want to inject dependencies in my applicationContext.xml file.
Is there a way I can keep the annotation-driven request-mapping but use context.xml files for Dependency Injection? Or is it only possible to use EITHER annotations OR xml configuration?
note: my beans for dependency injection are in a different xml file.
PS:
I should have mentioned, I use Spring 2.5 and can't upgrade it.
No, <mvc:annotation-driven> works fine with XML. But you'll need to get rid of the <context:component-scan>.
Update: with Spring 2.5, this should get you started:
<?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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<context:annotation-config />
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
<!-- now add some controllers -->
</beans>
Yes this is certainly possible.
To use the controller annotations such as #Controller and #RequestMapping make sure you put
<mvc:annotation-driven/>
in your <servletname>-servlet.xml
Then simple define your controllers using the normal XML bean notation such as:
<bean class="com.company.controllers.AController">
<property name="propertyName" ref="beanId" />
</bean>
These bean refs can come from any other applicationContext.xml defined in your web.xml too.

spring basic mvc sample application, annotation scan confusion

Little confused, the basic spring mvc app has this:
app-config.xml
<context:component-scan base-package="org.springframework.samples.mvc.basic" />
and the mvc-config.xml has:
<!-- Configures the #Controller programming model -->
<mvc:annotation-driven />
Do you really need both?
for component-scan, does this mean if I don't put the correct package path my #Controller and #Service markers will have no effect?
If I need more than one package, do I just duplicate the entry?
I tried using just the mvc:annotation-driven but that didn't work, I had to put com.example.web.controllers in the component-scan xml node to make it work.
context:component-scan is clear
Scans the classpath for annotated components that will be auto-registered as Spring beans. By default, the Spring-provided #Component, #Repository, #Service, and #Controller stereotypes will be detected.
So #Controller is just a Spring bean. Nothing else.
And
mvc:annotation-driven
registers the HandlerMapping and HandlerAdapter required to dispatch requests to your #Controllers
Which is similar to
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
If I need more than one package, do I just duplicate the entry?
You can if you want. context:component-scan is just a bean post-processor.
<context:component-scan base-package="br.com.app.view.controller"/>
<context:component-scan base-package="br.com.app.service"/>
Or
Use a comma-separated list of packages to scan for annotated components.
<context:component-scan base-package="br.com.app.view.controller,br.com.app.service"/>
mvc:annotation-driven allows you to configure behavior of Spring MVC. See details in documentation .For basic usage of Spring MVC you do not need it.
If you need more than one package just mention parent one: <context:component-scan base-package="org.springframework.samples.mvc" />

Resources