Spring java config EJB proxy not working - java

I have a problem getting EJB beans working when using Spring's java config classes.
Specifically I have the following that works:
#Configuration
#ComponentScan(basePackages = "com.company.web.config")
#ImportResource(value = {"classpath:spring-beans.xml"})
public class AppConfig {
}
#Configuration
#ComponentScan(basePackages = "com.company.web")
public class WebConfig extends WebMvcConfigurationSupport {
// basic Spring MVC setup omitted
}
My spring-beans.xml looks like this:
<?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:jee="http://www.springframework.org/schema/jee"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd">
<jee:local-slsb id="fooService" jndi-name="java:app/model/FooServiceBean!com.company.ejb.FooService"
business-interface="com.company.ejb.FooService" />
</beans>
With this configuration, everything works, and I can do this:
#Controller
public class HomeController {
private final FooService fooService;
#Autowired
public MyPageController(FooService fooService){
this.fooService = fooService;
}
// request methods
}
Now i try to get rid of the XML file. According to the documentation the local-slsb should be equivalent
<bean id="fooService"
class="org.springframework.ejb.access.LocalStatelessSessionProxyFactoryBean">
<property name="jndiName" value="java:app/model/FooServiceBean!com.company.ejb.FooService"/>
<property name="businessInterface" value="com.company.ejb.FooService"/>
</bean>
However, if I remove the #ImportResource from AppConfig and put this #Bean method instead, deployment fails because the Controller cannot be instantiated (no autowire candidates found for FooService):
#Bean
public LocalStatelessSessionProxyFactoryBean fooService(){
LocalStatelessSessionProxyFactoryBean factory = new LocalStatelessSessionProxyFactoryBean();
factory.setBusinessInterface(FooService.class);
factory.setJndiName("java:app/model/FooServiceBean!com.company.ejb.FooService");
return factory;
}
Any ideas why this doesn't work? I am using Spring version 4.0.2.

It seems that the issue was related to the order in which configuration was read, and possibly double configuration loading.
Specifically, introducing a separate configuration class and importing it before WebConfig seems to do the trick, like so:
#Configuration
#Import({EJBConfig.class, WebConfig.class})
public class AppConfig {
}
#Configuration
public class EJBConfig {
#Bean
public LocalStatelessSessionProxyFactoryBean fooService(){
LocalStatelessSessionProxyFactoryBean factory = new LocalStatelessSessionProxyFactoryBean();
factory.setBusinessInterface(FooService.class);
factory.setJndiName("java:app/model/FooServiceBean!com.company.ejb.FooService");
return factory;
}
}
#Configuration
#ComponentScan(basePackages = "com.company.web")
public class WebConfig extends WebMvcConfigurationSupport {
// basic Spring MVC setup omitted
}

Related

Is there any annotation equivalent of "default-lazy-init" attribute in Spring Framework?

How can I set this attribute in my JavaConfig application context?
<beans default-lazy-init="true">
<!-- no beans will be pre-instantiated... -->
</beans>
The Spring org.springframework.context.annotation.Lazy annotation indicates whether a bean is to be lazily initialized.
You can add it to a #Configuration class, a #Bean method or a #Component (for example #Service annotated class)
Example for a single bean:
#Configuration
public class MyConfig {
#Bean
#Lazy
public Example myLayzBean() {
return new Example();
}
}
Example for all beans in one configuration class
#Configuration
#Lazy
public class MyConfig {
#Bean
public Example1 myLayzBean1() {
return new Example1();
}
#Bean
public Example2 myLayzBean2() {
return new Example2();
}
}
Example for bean found by component scan
#Service
#Lazy
public class Example3 {
}

SpringMVC Jackson2HttpMessageConverter customization doesn't work

I want to use custom JsonSerializer for JSON response of SpringMVC4.
In order to add JsonSerializer, I created WebMvcConfigurerAdapter subclass.
But customization of MappingJackson2HttpMessageConverter didn't work.
Simplify the problem, I tried setJsonPrefix.
But it also didn't work. The response didn't changed.
My code is below. Please tell me what is wrong.
ControllerClass
#Controller
public class SampleController {
#RequestMapping("/sample")
#ResponseBody
public ResponseModel action() {
return new ResponseModel();
}
public static class ResponseModel {
public String id = "001";
public String text = "aaa";
}
}
Configuration
#Configuration
#EnableWebMvc
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(converter());
super.configureMessageConverters(converters);
}
#Bean
protected MappingJackson2HttpMessageConverter converter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setJsonPrefix("prefix");
return converter;
}
}
dispatcher-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
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/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
xmlns:aop="http://www.springframework.org/schema/aop">
<!-- base package -->
<context:annotation-config />
<context:component-scan base-package="jp.co.xxx.*" /><!-- my package. contains WebMvcConfiguration class -->
<annotation-driven />
<!-- aop -->
<aop:aspectj-autoproxy />
</beans:beans>
Note.
When server starts, configureMessageConverters method was called.
(Breakpoint confirmation)
I am using AbstractJsonpResponseBodyAdvice subclass for JSONP
(I removed this class, but nothing was changed.)
I used below as reference.
How to configure MappingJacksonHttpMessageConverter while using spring annotation-based configuration?
http://www.baeldung.com/spring-httpmessageconverter-rest
SpringMVC version is 4.1.6
P.S.
In JSONSerializer case is below.
#Configuration
#EnableWebMvc
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {
#Autowired
protected CustomObjectMapper mapper;
#Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(converter());
super.configureMessageConverters(converters);
}
#Bean
protected MappingJackson2HttpMessageConverter converter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(mapper);
return converter;
}
}
ObjectMapper
#Component
public class CustomObjectMapper extends ObjectMapper {
private static final long serialVersionUID = -6987863269632420904L;
public CustomObjectMapper() {
setSerializationInclusion(Include.NON_NULL);
enable(SerializationFeature.INDENT_OUTPUT);
SimpleModule module = new SimpleModule();
module.addSerializer(DateTime.class, new DateTimeSerializer());
registerModule(module);
}
}
In each case I had no error. But customization didn't work.
In the configureMessageConverters method, if you are not covered and no other converter is added, converters are empty, and WebMvcConfigurationSupport will call addDefaultHttpMessageConverters, which will configure the default converter, which contains the default MappingJackson2HttpMessageConverter.
So adding MappingJackson2HttpMessageConverter in extendMessageConverters will not work.
There are two solutions:
You add the required converter in the configureMessageConverters method itself
To determine the type of converter in extendMessageConverters, set the required properties
sorry,i speek broken english.
I was having this problem as well and discovered this problem, thanks to another site:
#EnableWebMvc is equivalent to in XML based configuration.
If you have BOTH, then the extendMessageConverters doesn't seem to be effective. As soon as I removed the XML entry, bingo.. the custom converters started working.

AOP using AspectJ not working in spring?

My Aspect class will be ,
#Configuration
#EnableAspectJAutoProxy
#Component
#Aspect
public class AspectClass {
#Before("execution(* com.pointel.aop.test1.AopTest.beforeAspect())")
public void logBefore(JoinPoint joinPoint) {
System.out.println("Before running the beforeAspect() in the AopTest.java class!");
System.out.println("Hijacked Method name : " + joinPoint.getSignature().getName());
System.out.println("************************");
}
}
My other java Class
public class AopTest {
public void beforeAspect() {
System.out.println("This is beforeAspect() !");
}
}
My Main Class is
public class MainMethod {
public static void main(String[] args) {
ApplicationContext context = new FileSystemXmlApplicationContext("ApplicationContext/applicationContext.xml");
AopTest test = (AopTest)context.getBean("bean1");
test.beforeAspect();
}
}
My applicationContext.xml 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: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/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
<bean id="bean1" class="com.pointel.aop.test1.AopTest" />
</beans>
In this the #Before("execution(* com.pointel.aop.test1.AopTest.beforeAspect())") in the AspectClass will not be executed before the beforeAspect() in the AopTest , when running Main method.
Good answers are definitely appreciated.
First of all if you're going to use an annotation based configuration, use AnnotationConfigApplicationContext instead of FileSystemXmlApplicationContext. And get rid of the applicationContext.xml file and simply add a #Bean method in your configuration class. Something like this:
#Configuration
#EnableAspectJAutoProxy
#ComponentScan(basePackages = "your.aspect.package")
public class AspectConfig {
#Bean
public AopTest aopTest() {
return new AopTest();
}
}
In your main
public class MainMethod {
public static void main(String[] args) {
AnnotationConfigApplicationContextcontext = new AnnotationConfigApplicationContext(AspectConfig.class);
// don't forget to refresh
context.refresh();
AopTest test = (AopTest)context.getBean("aopTest");
test.beforeAspect();
}
}
In AspectClass you should have #Component, #Aspect, and your method should have the advice or pointcut annotation like #Before. It needs to be a #Component, so that Spring knows to scan it.
Here some code need to add in xml to use annotations-
1.for #component annotation.
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd"
2.after that use component scan to get all annotated bean class which use #component annotation,and use aop autoproxy-
<context:annotation-config/>
<context:component-scan base-package="mypackage"></context:component-scan>
<aop:aspectj-autoproxy>
</aop:aspectj-autoproxy>
for examples visit-www.technicaltoday.com/p/spring.html
You are missing the point cut definition in your aspect class.
For example;
#Pointcut("execution(* *.advice(..))")
public void logBefore(){}
#Before("logBefore()")
public void beforeAdvicing(){
System.out.println("Listen Up!!!!");
}
You first have to defin the point to weave your aspect to. You do this by using Point cuts.It is the point cut name you give within your #Before annotation. Have a look at my blog post for more information # http://dinukaroshan.blogspot.com/2010/06/aop-with-spring.html
I don't see your AspectClass in the beans configuration. You should also declare it as a Bean.

How to enable <aop:aspectj-autoproxy> with java-based annotations

I am trying to set up Spring AOP without any XML.
I'd like to enable <aop:aspectj-autoproxy> in a class which is
annotated with #Configuration.
This is the way it would be defined in an XML-file:
<aop:aspectj-autoproxy>
<aop:include name="msgHandlingAspect" />
</aop:aspectj-autoproxy>
I tried to annotate my class with #Configuration and #EnableAspectJAutoProxy
but nothing happened.
Did you create an aspect bean in the same #Configuration class?
Here's what the docs suggest:
#Configuration
#EnableAspectJAutoProxy
public class AppConfig {
#Bean
public FooService fooService() {
return new FooService();
}
#Bean // the Aspect itself must also be a Bean
public MyAspect myAspect() {
return new MyAspect();
}
}
I used the accepted answer solution but I had unexpected problems and never understand untill to add this parameter to configuration.
#EnableAspectJAutoProxy(proxyTargetClass = true)
If you use annotation into #Controller you'll need to configure in this way
remember if you have java 8 you need to use a version of AspectJ greater than 1.8.X
#Configuration
#EnableAspectJAutoProxy(proxyTargetClass = true)
public class AppConfig {
#Bean
public AccessLoggerAspect accessLoggerAspect() {
return new AccessLoggerAspect();
}
}

Equivalent of mvc:default-servlet-handler in Spring annotation-based configuration?

Is it possible to have the equivalent of <mvc:default-servlet-handler/> defined in an AnnotationConfig(Web)ApplicationContext? Right now I have:
#Configuration
#ImportResource("classpath:/mvc-resources.xml")
class AppConfig {
// Other configuration...
}
with just the following in my resources/mvc-resources.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<mvc:default-servlet-handler/>
</beans>
And it works as expected. Is it possible to do this without importing an XML file? It would be a nice way to cut down on some boilerplate.
If you are using Spring 3.1 with WebMvc, you can configure default servlet handling like this:
#Configuration
#EnableWebMvc
public class MvcConfig extends WebMvcConfigurerAdapter {
#Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
After digging a bit deeper, I found out that this is a known problem and is addressed by annotation features in the upcoming Spring 3.1.
I solved my problem with the following code:
#Configuration
#Import(FeatureConfig.class)
class AppConfig {
...
}
#FeatureConfiguration
class FeatureConfig {
#Feature
public MvcDefaultServletHandler defaultHandler() {
return new MvcDefaultServletHandler();
}
}
This does require using the milestone version of spring, though, but it seems to be the cleanest and preferred way of handling this.
I don't think you can do it out of the box, but you can probably copy what DefaultServletHandlerBeanDefinitionParser does: Create a Bean of type DefaultServletHttpRequestHandler and map it to the URL scheme /**.
I'd say your Bean should subclass DefaultServletHttpRequestHandler and do the mapping in a #PostConstruct method.
#Bean
public DefaultServletHttpRequestHandler defaultServletHttpRequestHandler() {
return new DefaultServletHttpRequestHandler();
}
#Bean
public SimpleUrlHandlerMapping simpleUrlHandlerMapping() {
Map<String, String> urlMap = new ManagedMap<String, String>();
urlMap.put("/**", defaultServletHandlerName);
SimpleUrlHandlerMapping hm = new SimpleUrlHandlerMapping();
hm.setUrlMap(urlMap);
return hm;
}

Categories

Resources