How to test Spring service beans that themself have autowired dependencies? - java

I'd like to test some services that them themself contain other autowired services. But these "external" services are not required for the test itself.
How can I create a test setup, eg for the following example?
package de.myapp.service;
#Service
public class MyServiceDelegator {
#Autowired
private List<ServiceInterface> services;
public ServiceInterface delegate(String id) {
//routine to find the right ServiceInterface based on the given id
}
}
#Service
public class MyService implements ServiceInterface {
}
#Service
public class MyCustomService implements ServiceInterface {
//that is the problem during testing
#Autowired
private de.myapp.repository.SomeDao dao;
}
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("applicationContext.xml")
public class ServiceDelegatorTest {
#Autowired
private ApplicationContext ac
#Test
public void testDelegator() {
MyServiceDelegator dg = ac.getBean(MyServiceDelegator.class);
ac.delegate("test");
}
}
applicationContext.xml:
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="de.myapp.service" />
</beans>
Problem: All services that contain autowired dependencies from packages that are not scanned within the JUnit test (like MyCustomService), will throw an Exception:
Caused by:
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type [SomeDao] 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)}
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1103)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:963)
at
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
... 57 more

You can use Springockito to add mocked service implementations to your test application context.
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mockito="http://www.mockito.org/spring/mockito"
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
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
http://www.mockito.org/spring/mockito
http://www.mockito.org/spring/mockito.xsd">
<context:component-scan base-package="de.myapp.service" />
<mockito:mock id="dao" class="de.myapp.repository.SomeDao" />
</beans>

The problem is that SomeDao is not being picked up by component scanning because it's not under the de.myapp.service package.
You have explicitly stated that the package for component scanning is de.myapp.service.
I sugggest you make the following change:
<context:component-scan base-package="de.myapp" />
That way all the code under de.myapp will be eligible for component scanning.
If you want to avoid including all your code in component scanning you could do the following:
<context:component-scan base-package="de.myapp.service, de.myapp.repository" />

Related

Writing a JUnit test for a "Step" scoped bean - No scope registered for scope name "step" (Spring Batch 3.0.10)

I want to write a JUnit test case for a Spring managed bean which has the scope as "step". This bean is refereed by a Spring Batch Tasklet.
Bean defintion for configDAO ConfigDAOImpl class
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:batch="http://www.springframework.org/schema/batch"
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/tx
http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/batch
http://www.springframework.org/schema/batch/spring-batch.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- bean has been defined with a scope of "step" as it uses the stepExecutionContext -->
<bean id="configDAO"
class="com.myproject.common.dataaccess.impl.ConfigDAOImpl" scope="step">
<property name="jdbcTemplate" ref="jdbcTemplate" />
<property name="corePoolSize" value="${threadpool.size}"/>
<property name="frequency" value="#{stepExecutionContext['frequency']}" />
</bean>
</beans>
JUnit test case for the above bean
#RunWith(SpringJUnit4ClassRunner.class)
#PropertySource("classpath:properties/common.properties")
#ContextConfiguration(locations = { "/spring/common-context.xml" })
public class ConfigDAOImplTest {
#Autowired
private ConfigDAOImpl configDAO;
#Spy
private ContextParamDAO contextParamDAO = new ContextParamDAOImpl();
private static final String SCHEMA_CONFIG = "classpath:data/CONFIG_SCHEMA.sql";
private static final String DATA_CONFIG = "classpath:data/CONFIG_DATA.sql";
#Before
public void init() {
MockitoAnnotations.initMocks(this);
DataSource dataSource = new EmbeddedDatabaseBuilder()
.setType(EmbeddedDatabaseType.H2)
.addScript(SCHEMA_CONFIG)
.addScript(DATA_CONFIG)
.build();
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
//override the jdbcTemplate for the test case
configDAO.setJdbcTemplate(jdbcTemplate);
configDAO.setContextParamDAO(contextParamDAO);
}
//.. more coode
}
When I run the above test class, it fails with the following exception :
Caused by: java.lang.IllegalStateException: No Scope registered for scope name 'step'
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:343)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
I tired added #EnableBatchProcessing annotation above my test class but that did not resolve the issue.
How can I write a JUnit test for a step scoped bean?
You'll find more information in the official documentation, there's a section called "Testing Step-Scoped Components". But for a start you should annotate your Test with these two annotations (pre Spring 4.1) enabling your step scope.
#TestExecutionListeners( { DependencyInjectionTestExecutionListener.class,
StepScopeTestExecutionListener.class })
Or this annotation, for Spring 4.1+
#SpringBatchTest
You then also need to define a StepExecution, similar to this (and taken from the documentation)
public StepExecution getStepExecution() {
StepExecution execution = MetaDataInstanceFactory.createStepExecution();
execution.getExecutionContext().putString("input.data", "foo,bar,spam");
return execution;
}

Autowired Spring REST web service with Neo4J

I'm trying to develop a simple REST WS that connects to an embedded Neo4J DB that runs locally on my machine. First I got a simple GET operation just returning a simple String when the Service was called and that works normally. Now I'm trying to get this to really do something so I've searched a couple of tutorials on how to integrate Spring with Neo4J. The truth is I've found this to be much more tricky than what I was expecting, mainly because there's a lot of tutorials and they all look different, so there's like 100 different ways to do it and I'm trying to adapt to my solution. I'm not sure on my Annotations and also on my XML configuration files. Any help is apreciatted. May the Force be with me. :)
UPDATE_1: this is myStore servlet now
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:mvc="http://www.springframework.org/schema/mvc" 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 http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">
<mvc:annotation-driven />
<context:component-scan base-package="com.ruitex23.myStore" />
<jpa:repositories base-package="com.ruitex23.myStore.repositories" />
<bean name="soapOperationRepository" class="com.ruitex23.myStore.services.SoapOperationService" />
<context:annotation-config />
</beans>
The Controller
package com.ruitex23.myStore.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.ruitex23.myStore.domains.SoapOperation;
import com.ruitex23.myStore.services.SoapOperationService;
#RestController
public class SpringRestController {
#Autowired SoapOperationService operationService;
//the dummy method
#RequestMapping(value = "/hello/{name}", method = RequestMethod.GET)
public String hello(#PathVariable String name) {
String result = "Hallo " + name;
return result;
}
//the real method
#RequestMapping(value = "/soapOperation/{version}", method = RequestMethod.GET)
public SoapOperation getSoapOperationByVersion(#PathVariable("version") Integer version) {
return operationService.searchBySoapOperationVersion(String.valueOf(version));
}
}
The Repository
package com.ruitex23.myStore.repositories;
/**
*
*/
import org.springframework.data.neo4j.repository.GraphRepository;
import org.springframework.data.repository.query.Param;
import com.ruitex23.myStore.domains.SoapOperation;
/**
* #author ruitex23
*
*/
public interface SoapOperationRepository extends GraphRepository<SoapOperation> {
SoapOperation findBySoapOperationVersion(#Param("soapOperationVersion") String soapOperationVersion);
}
The Service
package com.ruitex23.myStore.services;
/**
*
*/
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruitex23.myStore.domains.SoapOperation;
import com.ruitex23.myStore.repositories.SoapOperationRepository;
/**
* #author ruitex23
*
*/
#Service
public class SoapOperationService {
#Autowired SoapOperationRepository soapOperationRepository;
public SoapOperation searchBySoapOperationVersion(String operationVersion) {
return soapOperationRepository.findBySoapOperationVersion(operationVersion);
}
}
MyStore Servlet
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" 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 http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<mvc:annotation-driven />
<context:component-scan base-package="com.ruitex23.myStore" />
//read somewhere that the interface should point to the impl
<bean name="soapOperationRepository" class="com.ruitex23.myStore.services.SoapOperationService" />
<context:annotation-config />
</beans>
web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>myStore</display-name>
<servlet>
<servlet-name>mystore</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mystore</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
And now the error related to the Autowired object.
12:05:58.649 [main] WARN o.s.w.c.s.XmlWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'springRestController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.ruitex23.myStore.services.SoapOperationService com.ruitex23.myStore.controllers.SpringRestController.operationService; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'soapOperationService': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.ruitex23.myStore.repositories.SoapOperationRepository ruitex23.myStore.services.SoapOperationService.soapOperationRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.ruitex23.myStore.repositories.SoapOperationRepository] 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)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334) ~[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1214) ~[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) ~[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) ~[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE]
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:305) ~[spring-beans-4.2.1.RELEASE.jar:4.2.1.RELEASE]
The error continues on and on, but I think this the important part. If u need to see anything else of the log error let me know.
Thank in advance
You are missing the configuration for the repositories in your XML configuration file. In fact, as reported in the Creating repository instances/XML Configuration at the Spring Data Neo4j - Reference Documentation:
Each Spring Data module includes a repositories element that allows
you to simply define a base package that Spring scans for you
Now, what you need to add to add to your XML configuration file is the following snippet:
<jpa:repositories base-package="com.ruitex23.myStore.repositories" />
You have also to:
add the following schema definition in your <beans...> tag:
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
add the following schema location to your xsi:schemaLocation:
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd

Spring not autowiring using annotation a bean declared on the XML

I'm trying to inject a bean that was defined on a XML into an annotated, It is only annotated and not declared on XML, I think that is just something that I'm missing here is my *context.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:tx="http://www.springframework.org/schema/tx"
xmlns:jee="http://www.springframework.org/schema/jee"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jee
http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
...
<bean id="userBusiness" class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
<property name="jndiName" value="java:global/app-common/app-common-core/UserBusinessImpl" />
<property name="businessInterface" value="com.app.common.business.UserBusiness" />
</bean>
...
<context:annotation-config/>
<context:component-scan base-package="com.app.common.jsf" />
</beans>
Here's the component:
#Component
public class AppAuthorization {
#Autowired
private UserBusiness userBusiness;
#Autowired
private AppLogin sabiusLogin;
...
#Local
public interface UserBusiness {
User listUserByFilter(User user) throws UserBusinessException;
...
#Stateless
#Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT)
#Interceptors({SpringBeanAutowiringInterceptor.class})
public class UserBusinessImpl implements UserBusiness {
#Autowired
private ProgramasUsuariosDao programasUsuariosDao;
...
When I try to access the AppAuthorization Spring says that:
Could not autowire field: private com.app.common.business.UserBusiness com.app.common.jsf.AppAuthorization.userBusiness"
Seems that the annotated bean can't see the declared one, but search and seems that I only needed to add the annotation-config to the XML, is this right? Hope some can help me.
EDIT
I think that this is the most important part of the stack trace:
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.app.common.business.UserBusiness] 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)}
at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:997)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:867)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:779)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:503)
... 201 more
Following the steps on the context creation I see no bean registered tha can be seen by annotations just when springs creates the context based on the xml is that I can see all the beans that wre created.
EDIT 2
This is the beanRefContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="contexts" class="com.app.common.spring.ClassPathXmlApplicationContext" />
</beans>
This is the class that loads the XML context files:
public class ClassPathXmlApplicationContext extends org.springframework.context.support.ClassPathXmlApplicationContext {
public ClassPathXmlApplicationContext() {
super((System.getProperty("module.context.file").split(";")));
}
}
As I said, the annotated beans cannot see the XML ones so, spring cannot autowire them.
EDIT 3
I don't have a #Configuration bean (I'm not using AnnotationConfigApplicationContext), all the config is in the XML and if I try to create one the server doesn't start, it's a legacy system with spring 3.2 and EJB 3.0 and I can't change this aspect now.
Thanks in advance!
I think you missed to specify #Component annotation for the UserBusiness class
EDIT:
Can you make the component-scan config to com.app.common instead of com.app.common.jsf
What seems to work was create a #Configuration import the xml that have the bean declaration (with #ImportResource) and don't scan it's package in XML.
For some reason if I declare the file in the XML the server don't start, it's strange because I have no definition anywhere that I'm using an annotation configuration.

when i run my code No qualifying bean of type 'com.temp.dao.TempDao' available: expected at least 1 bean which qualifies as autowire candidate

my spring code is below. please any one explain what is wrong in my code.
TempImpl.class
#Component
#Transactional
public class tempImpl{
#Autowired
private TempController tempController;
public void temp_1(){
String status = tempController.saveTemp1();
}
}
TempController.class
#Component
public class TempController{
#Autowired
private TempDao tempDao;
public void saveTemp1(){
String status = tempDao.saveTemp1();
}
}
TempDao.class
#Component
public class TempDao{
public void saveTemp1(){
TempEntity tempEntity = new TempEntity();
tempEntity.seTemp1Value("hello");
}
}
xml config file is
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.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
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:annotation-config/>
<context:component-scan base-package="com.temp.dao" />
<context:component-scan base-package="com.temp.service" />
<context:component-scan base-package="com.temp.controller" />
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>
<bean id="transactionManager" class="org.springframework.transaction.jta.WebLogicJtaTransactionManager"/>
<!-- For Struts Action Class -->
<bean name="/saveTestAction" class="com.temp.tempAction" />
</beans>
when my code comes Dao class and while executing tempEntity.seTemp1Value("hello"); this line
No qualifying bean of type 'com.temp.dao.TempDao' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}

Spring #Aspect & Maven. Not working in external modules, but it's working witouth annotations

I've a question about Spring AOP and AspectJ, defining aspects, pointcut etc with annotations.
The context is this:
I have 2 maven modules (A and B).
Module B uses module A (via <dependency>...</dependency> in maven) and import his spring context.
I'm trying to write and use an very stupid test aspect (catch all public operations).
This aspect is defined in module A,
I wan't that this aspect works when I call any public operation in A or B.
Well, now the "postergeist". My first aproach was define all in XML. Aspect, pointcut, etc. And it works really well. This is the code:
ApplicationContext
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<aop:config>
<aop:aspect id="myAspectAOP" ref="myAspect">
<aop:around method="validateCall"
pointcut="execution(public * *(..))" />
</aop:aspect>
</aop:config>
<context:component-scan base-package="com.mypackage"/>
</beans>
MyAspect.java and Test.java is the same that the next case (without Aspect annotations). I don't put it here yet to avoid spreading much text.
That works fine!
Ok, next aproach. Using annotations. This is the code:
ApplicationContext
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<aop:aspectj-autoproxy />
<context:component-scan base-package="com.mypackage"/>
</beans>
And MyAspect class
#Aspect
#Component //I have tried without this annotation, and it doesn't work
public class MyAspect {
#Pointcut("execution(public * *(..))")
public void allPublic() {
}
#Around("allPublic()")
public Object validateCall(final ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
// Some Code
}
}
Test.java (package com.mypackage)
#Component
public class Test{
public void foo(){
//Some code
}
}
In this case:
when I put Test.java into module B and call an public operation (remember, class is in B module), it doesn't work.
BUT when I put Test.java into A Module and I call a public operation (It's in A module), it works. It looks like only works with calls to public operations of classes defined into the same module where Aspect is defined (A module), but not in "externals" (B Module). Remember. B module includes/uses A Module and import his context. But it isn't happening when I use "xml declaration" instead of "annotations declaration"
Important: MyAspect.java is in A Module allways
Remember, in the first case (defining all in applicationContext, and not using #Aspect #Pointcut,#...) works allways, in B and A module public operations.
In both cases, the classes are into com.mypackage, so are injected by spring.
I'm really lost, It's the first time I get this kind of "postergeist", and I have been looking and looking into Spring documentation an google for days, but I can't find any solution.
I'm using Spring 3.1.2 and Aspectj 1.6.11
Please, any idea?
Thanks!

Categories

Resources