Spring AOP for non-service Class - java

I am a beginner in Spring framework. I have implemented Spring AOP for logging method execution time. Using some examples from internet, I get it working for a Service interface as specified below. But the same code is not working if I change the expression to a non-service class. Have give below the CXF configuration.
<bean id="xbean" class="com........xServiceImpl" />
<jaxrs:server id="xServiceRS" address="/xRSService">
<jaxrs:serviceBeans>
<ref bean="xbean" />
</jaxrs:serviceBeans>
</jaxrs:server>
<bean id="performanceLoggingAdvice" class="com......PerformanceLoggingAdvice" />
<aop:config>
<aop:pointcut id="performanceLoggingPointcut"
expression="execution(* com.....xService.*(..))" />
<aop:advisor advice-ref="performanceLoggingAdvice"
pointcut-ref="performanceLoggingPointcut" id="performanceLoggingInterceptorAdvisor" />
</aop:config>
i have already searched in stack overflow for the similar question but I did not get a useful and specific answer to my question. Any idea what could be the issue ? How to get it working for a non service class for example Utils.java ?
Thanks in Advance for helping me..

The Spring AOP advices are only applied on the instances of the classes declared as Spring beans. Make your Util class a Spring bean, use proper pointcuts and it should work.
You should obtain the Util instances only through the Spring application context in that case (by calling one of the ApplicationContext.getBean methods), not through a call to the constructor using new.

Related

Spring-Boot: Jmx annotation not working in library

I have a Spring-Boot application that just have a simple rest controller. On this controller, I added the jmx annotations #ManagedResource and #ManagedOperation and it is working fine. It is correctly exposed in Jmx.
This application depends on a "global-commons" library to share many basic functionality to all of our modules.
But if I add the same annotations to a class in this library, it is ignored!
And before you ask, yes the library is imported with the latest change.
There is no error or warning message in the logs.
I am configuring all my beans using an xml file. Both classes are beans defined in the same file.
One is a #RestController. The other one is a simple utility class.
Any idea?
Make sure the classes from the global-commons library as managed by Spring. As long as none of the classes in the library are managed by Spring, the annotions don't have any effect.
I found the problems:
The bean that was not working was defined as an "inner" bean:
<bean id="imMetrics" class="com.imetrik.global.common.metrics.ImGlobalMetrics" init-method="init">
...
<property name="reporterList">
<util:list>
<bean id="jmxReporter" class="com.imetrik.global.common.metrics.reporters.ImJmxReporter">
<property name="registryId" value="metricRegistry1"/>
<property name="durationUnit" value="SECONDS"/>
<property name="rateUnit" value="SECONDS"/>
<property name="domain" value="com.imetrik.global.metric"/>
</bean>
</util:list>
</property>
</bean>
The annotated beans is "jmxReporter".
But if I put it outside as a normal "first level" bean and use a reference instead, it is working.
But it is annoying! Is there a way to make it work even as a inner beans?

Using spring as configurator

I have a server application. Now I'm using Spring not only to inject dependencies, but also to config my application. Something like this:
<bean id="server" class="foo.bar.Server">
<property name="host" value="${config.host}"/>
<property name="someBean">
<ref bean="someBean"/>
</property>
</bean>
My colleague sad that configuring application in Spring is not obvious and we should avoid this. I see logic in his words, because Spring is for dependence injection and server port is not dependency, isn't it? But for me configuring application is Spring is very convenient and obvious. Is my colleague right?
Configuring in Spring is simple, clear and maintainable.
This way you can easily create several instances with different properties.

TransactionProxyFactoryBean when switching from configuration-based Service beans to annotation based service beans

I read about using
<context:component-scan base-package="tld.mydomain.business">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
</context:component-scan>
and annotate my service beans with #Service("myService"), and thought great, I'll do that, since I'm already doing that with my controllers. My usual service bean configuration looks like
<bean id="userService" parent="txProxyTemplate">
<property name="target">
<bean class="tld.mydomain.business.UserServiceImpl"/>
</property>
<property name="proxyInterfaces" value="tld.mydomain.business.UserService"/>
</bean>
so now that I generate them, how do I wrap them in a Hibernate proxy such as TransactionProxyFactoryBean? Or is there a better way to do that as well?
I have not yet gone all the way and used #Repository as well, is that required?
Cheers
Nik
Using TransactionProxyFactoryBean is not encouraged in modern Spring applications, although it still works. The typical approach nowadays is to annotate classes with #Transactional, and then stick this element in your application context file:
<tx:annotation-driven transaction-manager="txManager"/>
This and other strategies are discussed in great depth in the reference document, and there's even a side note about TransactionProxyFactoryBean.
There's no need for
<context:include-filter type="annotation"expression="org.springframework.stereotype.Service"/>
Spring will register #Service, #Repository, #Component... once they are found in the base package.
Like #Rob said either use #Transactional or <aop:config>...</aop:config> to handle your transactions at the service level.
If you have two different resources that need to be in the same transaction, then you will need to use JTA. See my answer to an earlier question here. Your config would need to look something like:
<tx:annotation-driven transaction-manager="txManager"/>
<bean id="txManager"
class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManagerName" value="appserver/jndi/path" />
</bean>
Where appserver/jndi/path would need to be replaced with the JNDI path of the JTA transaction manager that comes with your application server (although you can use a standalone JTA transaction manager such as JOTM as well). Typical paths as mentioned in the 2.5.x API are:
"java:comp/UserTransaction" for Resin 2.x, Oracle OC4J (Orion), JOnAS (JOTM), BEA WebLogic
"java:comp/TransactionManager" for Resin 3.x
"java:appserver/TransactionManager" for GlassFish
"java:pm/TransactionManager" for Borland Enterprise Server and Sun Application Server (Sun ONE 7 and later)
"java:/TransactionManager" for JBoss Application Server

Correct usage Of LOG4J in Spring Framework Via DI

I am trying to use Log4j as part of the Spring Framework,
as far as i understand through the use of a an appropriate bean
the system is supposed to map a singleton instance accessible in the code
while mapping the logging depth automatically to the class
Similar to the normal use of Log4J as in
Logger log = Logger.getLogger(getClass());
i have been using the following Spring bean definition
<bean id="log4jInitialization"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetClass"
value="org.springframework.util.Log4jConfigurer" />
<property name="targetMethod" value="initLogging" />
<property name="arguments">
<list>
<value>conf\log4j.xml</value>
</list>
</property>
</bean>
But i am unable to map this bean to a specific member in a given class
nor am i able to use it through #autowired
Please let me know if there are any better ways to integrate Log4j and Spring
Best Regards
Mark
The short answer to your question is that log4j is not DI friendly.
The Log4jConfigurer.initLogging() method has a void return value, so there's nothing to inject. The idea is that you call that method, which bootstraps log4j, and then you use the Log4j API as usual (using Logger.getLogger(getClass())).
You generally wouldn't configure Log4jConfigurer as a Spring bean, though, but more usually you'd invoke it directly from your own code during application startup.
If this is a webapp, then Spring provides alternatives to Log4jConfigurer that are better suited to that environment (Log4jWebConfigurer, Log4jConfigListener).
Incidentally, 2 years ago I filed a feature request to allow loggers to be autowired, and it's finally been marked as fix for Spring 3.1. Horray.

jersey integration with spring

I want to use Jersey 1.1 with spring 2.5. The exact thing that i need to do is write a interface which would be exposed as the service and implementation in a class that extends the interface.
I cannot do it in applicationContext.xml, maybe because the XSD has changed.
Could some one provide with a sample code/snippet/file where they have been able to implement this successfully.
Thanks in Advance,
Adhir Aima
got it finally.. the new schema does support the basic bean definitions so the interface and the implementation classes can be specified using the old technique
<bean id="myService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>com.poc.service.MyServiceInterface</value>
</property>
<property name="target" ref="myServiceimpl" />

Categories

Resources