I am moving from an xml config to annoations. i want to convert a session scoped bean that is
<aop:scoped-proxy>
can this be done with annotations, and if not, what can i do to still keep that declaration working?
edit:
I am interested in doing this in Spring 2.5
In Spring 3.0 it can be specified by the proxyMode attribute of #Scope annotation:
#Scope(value = "session", proxyMode = ScopedProxyMode.INTERFACES)
in the spring context xml, do something like:
<context:component-scan base-package="com.startup.failure" scoped-proxy="interfaces" />
Note that you would need to write interfaces for all classes in that package, though.
In Spring 2.5.x
If I do in spring-context.xml something like
<context:component-scan base-package="com.startup.failure" scoped-proxy="TARGET_CLASS" />
So this way I don't need my proxied beans to implement interfaces? (using CGLIB not JDK standard).
Didn't tested this but i think it should work.
Of course you need to have cglib library, you need it with <aop:scoped-proxy> anyway.
Related
We are upgrading from Spring 3.2.4 to Spring 4.3.8 in which singleton="false" is no longer supported. What is the way to set singleton 'false' in Spring 4.3.8?
If singeton="false" then does it means that spring bean scope has become "Prototype"?
You can use #Scope for specifying prototype bean.
Example:
#Bean #Scope("prototype")
public Person personPrototype() {
return new Person();
}
for further reading follow link
As far as I remember, singleton=false was kept for some compatibility reasons, also indicated in some older docs, eg 3.0.0.M3:
<bean id="accountService" class="com.foo.DefaultAccountService"/>
the following is equivalent, though redundant (singleton scope is the default); using spring-beans-2.0.dtd
<bean id="accountService"> class="com.foo.DefaultAccountService" scope="singleton"/>
the following is equivalent and preserved for backward compatibility in spring-beans.dtd
<bean id="accountService"> class="com.foo.DefaultAccountService" singleton="true"/>
Anyway, the default spring scope is singleton, so even when unspecified, but can be changed to prototype (or whatever you need) with:
XML: scope="prototype"
Java DSL: #Scope("prototype") or #Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
Correct, scope="prototype" is the direct equivalent of singleton="false".
The equivalent of singleton="false" is scope="prototype".
another alternative is to use the annotation #Scope("prototype")
The equivalent of singleton="true" would be to eliminate this attribute in the spring config, since scope="singleton" would be the default.
When specifying the XML configuration below:
<aop:aspectj-autoproxy>
<aop:include name="myBean" />
</aop:aspectj-autoproxy>
We all know that the #EnableAspectJAutoProxy annotation is the equivalent to the aspectj-autoproxy XML configuration but is there a java-based annotation equivalent for the aop:include XML configuration? I searched extensively and could not find.
Normally you tell Spring that you are using a particular feature, like Transaction management and it will create the proxies needed.
For instance #EnableTransactionManagement will cause Spring to create proxies for Components (services, controllers and repositories) which use #Transactional, you don't need to declare this, Spring automatically finds the beans that need to be proxied.
It works the same way with #EnableScheduling causing Spring to detect #Scheduled methods, and #EnableCaching to detect #Cached method.
I have created a custom annotation in my spring mvc project.
The annotation is used to do an AOP
#Around("execution(#Cached * * (..)) && #annotation(cache)")
Here the annotation that I have created is "Cached", any method with the annotation is cached in couch base with the response as its value and the method argument as its key.
The problem is the annotation works (AOP works) on the controllers well. However from controllers, I am making call to different callable classes and utils. When I add the annotation" #Cached" on the callable classes or the util funcations the AOP doesn't work.
In the XML file, the following is what I have declared.
<aop:aspectj-autoproxy/>
<context:spring-configured/>
<context:component-scan base-package="com.abc.xyz">
<!--<context:include-filter type="annotation" expression="org.aspectj.lang.annotation.Aspect"/>-->
</context:component-scan>
<bean id="universalController" class="com.abc.xyz.misc.UniversalController"/>
<bean class="com.abc.xyz.api.metric.SystemTiming"/>
<bean class="com.abc.xyz.api.annotations.URLCacheImpl"/>
With Spring AOP, your classes which match the pointcut (where you have placed your #Cached annotation in this specific case) should be Spring beans. So the best guess that I can make is that your utility classes are very likely not Spring beans and that is reason why they are not getting woven in. You have two options that I can think of:
Make your utility classes also clean Spring beans
Use full Aspectj support - this way even though your utility classes are not Spring beans they would be woven with the advice.
I am trying to use spring to provide managed beans to jsf. I assume that #ManagedBean will be picked up by JSF container to link the EL in JSF to managed bean even when I use spring by configuring spring usage in faces-config.xml.
Spring shall provide the beans but now who manages scope of the beans?
I have tried following annotation on beans to have it become Request scope but they do not work.
#ManagedBean(name="helloBean") //meant for JSF
#RequestScoped //meant for JSF
#Scope(value="request") //meant for spring
#Controller //meant for spring
public class HelloBean implements Serializable {
Actually earlier I was using plain JSF and #ManagedBean and #RequestScoped were working well. Now as I tried to integrate using spring the scope are not working.
I have even tried setting bean scope in spring config but they work as expected in context of spring (singleton and prototype) but not web request context.
I was trying to avoid having to use above #Scope and #Controller annotation hoping that JSF will manage scope but do not seem like.
Below are my files snippet for spring config and MyHelloBean which probably will help communicate better.
<bean id="helloBean" class="com.mkyong.common.HelloBean" init-method="init" />
<bean id="myHelloBean" class="com.mkyong.common.MyHelloBean" init-method="init" >
<property name="helloBean" ref="helloBean"></property>
</bean>
#ManagedBean
#RequestScoped
#Scope(value="request")
#Controller
public class MyHelloBean implements Serializable {
private static final long serialVersionUID = 1L;
//#ManagedProperty(value = "#{helloBean}")
private HelloBean helloBean;
see in above MyHelloBean I am using spring DI to set helloBean which gets set by spring fine. I have commented out #ManagedBean which I think I can leave it in there as it will be ignored by spring any ways and JSF is not going to process it I guess but to be safe I commented it out for JSF to not process it.
To complete I use below in faces-config to activate spring usage.
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
Regards,
Miten.
Our team faced similar problems integrating JSF and Spring beans, including problems with their scopes. And here I am to share our knowledge.
Scopes
Basically now, when you defined in your application context, that Spring will be managing your beans, thus scopes. Spring will map JSF scope annotations to his native scope annotations.
Example when both Spring and JSF support provided scope:
#RequestScoped annotation will be mapped to #Scope("request") Spring's annotation, etc with other supported scopes.
Example when Spring does not support JSF's provided scope:
#ViewScoped is not defined in Spring's native scope annotations, thus (not sure) it will use Spring's default scope, which is singleton, or request scope (not sure).
Bean Injection
In JSF2 you used #ManagedProperty annotations for injection, while Spring uses #Autowired annotation. What are the differences and which to choose?
Injecting Spring beans with #ManagedProperty:
Spring component you wish to inject must have a value which will match jsf injection annotation's value: #Component(value = "valueMatches") injected with #ManagedProperty(value = "valueMatches").
Injecting Spring beans with #Autowired:
Spring component you wish to inject must does not require a custom value to distinguish, if it is the only implementation of the bean you are injecting: #Component injected with #Autowired.
Our way
We used Spring's annotations for defining Beans, Scopes and Injection.
We marked JSF beans with #Scope(value = "desiredScope"), #Controller(value = "beanName") and #Qualifier(value = "beanName") annotations. Later which could be accessed from JSF context with help of in faces-config.xml via "beanName" value defined in the #Controller annotation.
We marked Spring services with #Service annotation.
We injected Spring services and JSF beans with #Autowired annotation.
We found ViewScope and FlashScope custom implemetations on the web and used them for our beans. Thus we did not lose any of JSF2 scopes and even added new one.
Hope this helps.
Your approach is a bit confusing in the sense that it seems that you're mixing Spring XML configuration and Spring Annotation-based configuration. As described as an example here, if you're using annotated configuration then you should have:
<context:component-scan base-package="com.yourcom.package" />
to order Spring scan for the annotations. Otherwise, if you're using XML configuration then you should have:
<bean id="helloBean" class="com.mkyong.common.HelloBean" init-method="init" scope="request" />
as by default the scope for a Spring bean is singleton.
Is it possible to autowire beans using the #Autowired annotation without using component scanning?
Yes. <context-component-scan .. /> is responsible for discovering beans annotated with #Component, #Controller, #Service, #Respository, etc.
In order to have annotations processed (#Autowired, #Resource, etc) you need <context:annotation-config />. Thus annotations are processed on beans that are listed in applicationContext.xml.
As far as I know, <context-component-scan .. /> activates <context:annotation-config /> automatically.
This is true for both spring 2.5 and 3.0. (thanks skaffman)
I have never tried without component-scanning enabled, however I can confirm that #Autowire annotations works in Spring 3.0.x even with beans that are defined via XML.
When using AnnotationConfigApplicationContext, annotation config processors are always registered, meaning that any attempt to disable them at the #ComponentScan level would be ignored.
If it is meant in the question that you should explicitly state:
- <context:component-scan ...> in your xml file(it enables <context:annotation-config />)
or
- #ComponentScan in your java config
Then the answer is - Yes, it is possible to enable component scanning without any of the stated above statements in your code or xml file.
Another approach is to use AnnotationConfigApplicationContext :
AnnotationConfigApplicationContext context=
new AnnotationConfigApplicationContext("org.example.your.package");
Where "org.example.your.package" is your package for stereotyped annotated classes: #Component, #Repository, #Service, etc.
AnnotationConfigApplicationContext will search for your beans in the base package and inner packages.
No, we must use #ComponentScan if you are using java based configuration
(or) <context-component-scan .. /> for xml based configuration.
Note: If you are not using any of the approaches no corresponding instances are created in AplicationContext.
and when you try to access a resource (http://localhost:8080/customers) will end up with
WARNING: No mapping found for HTTP request with URI [/customers] in
DispatcherServlet with name 'dispatcher