Announcement Announcement Module
Collapse
No announcement yet.
Spring AOP - Standalone application but without Spring DI Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring AOP - Standalone application but without Spring DI

    Hi all,

    I am working since 3 year on a tag & rename standalone (Swing) application for audio files with Discogs integration. Now I want to explore some more in aspects and aop...

    I want to use Spring AOP in my application because it can add some good functionality in my oppinion like logging, would love to have that working with AOP and security also... anyways I don't use Spring for managing my beans... because I do that myself. I tried to use Spring DI but I couldn't build a proper executable jar because Spring threw weird exceptions I have never seen before... After few weeks trying I postponed it because of a deadline ... So for now I try to make it work without Spring managing my beans and instances ...

    My question is, can I use beans I manage myself in combination with the Spring AOP facilities ?

    I have a log aspect:

    Code:
    @Aspect
    public class CoreLogAspect {
    
    	private static final Logger LOGGER = LoggerFactory.getLogger(CoreLogAspect.class);
    	
    	public CoreLogAspect() {
    		super();
    	}
    	
    	@Around("execution(* be.elitetagger.core.*(..))")
    	public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {
    
    		LOGGER.trace("ENTRY - method ...");
    		
    		LOGGER.trace("***** - Hijacked method: " + joinPoint.getSignature().getName());
    		LOGGER.trace("***** - Hijacked arguments: " + Arrays.toString(joinPoint.getArgs()));
    		
    		joinPoint.proceed();
    		
    		LOGGER.trace("LEAVE - method ...");
    	}
    }
    and a spring-aop.xml file on classpath (spring/spring-aop.xml):

    HTML Code:
    <?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.1.xsd
    						   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd ">
    
    	<aop:aspectj-autoproxy/>
    	
    	<bean id="coreLogAspect" class="be.elitetagger.core.aspect.CoreLogAspect"/>
    </beans>
    and a config reader class to load it:



    Code:
    package be.elitetagger.core.aop;
    
    import org.apache.commons.lang.builder.ToStringBuilder;
    import org.apache.commons.lang.builder.ToStringStyle;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import be.elitetagger.core.exception.ExceptionHandler;
    
    public class SpringAopConfigReader implements AopConfigReader {
    
    	private static final Logger LOGGER = LoggerFactory.getLogger(SpringAopConfigReader.class);
    	
    	private static final String DEFAULT_SPRING_CONTEXT_PATH = "spring/spring-aop.xml";
    	
    	private ApplicationContext springApplicationContext;
    	
    	public ApplicationContext getSpringApplicationContext() {
    		return springApplicationContext;
    	}
    	
    	public SpringAopConfigReader() {
    		super();
    	}
    
    	@Override
    	public boolean readConfiguration() {
    		return readConfiguration(DEFAULT_SPRING_CONTEXT_PATH);
    	}
    	
    	@Override
    	public boolean readConfiguration(String strContextPath) {
    		
    		LOGGER.debug("Reading Spring AOP configuration ...");
    		
    		try {
    			springApplicationContext = new ClassPathXmlApplicationContext(strContextPath);
    		} catch(BeansException ex) {
    			LOGGER.error(ExceptionHandler.getStackTrace(ex), ex);
    			return false;
    		}
    		return true;
    	}
    }
    When I initialize my application, the aop.xml file is parsed successfully and aspect is initialized. No errors on loading the xml file..

    Now for me, I think it's logic because Spring normally auto proxy the beans that are managed by Spring container.

    Now is it possible to use Spring AOP facilities but without Spring managing my beans ? Perhaps a weird question ??? I use Spring a lot at work in web applications but I have no clue how to integrate it well in a standalone application... The component scanning in standalone applications doesn't work as well as in web applications. Still love spring a lot ! Respect..

    Thanks in advance !

    Greets,


    Sikke

    forgot to mention, I use Spring v3.1

    PS: For those who are interested => www.facebook.com/elitetaggerpro (win only, for now)
    Last edited by Kristof303; Aug 29th, 2012, 01:54 PM.

  • #2
    No, you can't use Spring AOP without using Spring DI because Spring AOP only works on beans defined in Spring, which Spring knows of and manages. However you can use AOP without Spring, just use standalone AspectJ: write your aspects in the AspectJ language, and use the AspectJ compiler to compile your code.

    Comment


    • #3
      I found what it was !

      Because I use annotations for my aspects, I had to add <context:annotation-driven/> to xml configuration. Besides that, because my beans don't implement LoadTimeWeaverAware interface, you need spring instrumentation (java agent) on classpath so you can literally weave aspects at runtime.. and make Spring aware of external beans that are NOT managed by Spring.

      also adding => -javaagent:spring-instrument-3.1.0.RELEASE.jar as JVM argument to load them on JVM startup. I had to copy the jar to my current directory. Still need to figure it out to load the agent on startup. But I think how to solve it... found a good solution ! Let me know if interested !

      aspect:

      Code:
      @Aspect
      public class CoreLogAspect implements Serializable {
      
      	private static final long serialVersionUID = -9115824744276979998L;
      	
      	private static final Logger LOGGER = LoggerFactory.getLogger(CoreLogAspect.class);
      	
      	/**
      	 * Constructor
      	 */
      	public CoreLogAspect() {
      		super();
      	}
      	
      	@Pointcut(value = "execution(public * be.elitetagger.core..*.*(..))")
      	public void everyPublicMethod() {
      		
      	}
      	
      	@Around(value = "everyPublicMethod()")
      	public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
      
      		final String methodName = joinPoint.getSignature().getName();
      		
      		LOGGER.trace("ENTRY - method [ {} ] ...", methodName);
      		
      		LOGGER.trace("***** - Hijacked arguments: " + Arrays.toString(joinPoint.getArgs()));
      		
      		final Object object = joinPoint.proceed();
      		
      		LOGGER.trace("LEAVE - method [ {} ] ...", methodName);
      	
      		return object;
      	}
      }
      spring-aop xml looks like this:

      HTML Code:
      <?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"
      	   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.1.xsd
      						   http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
      						   http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
      
      	<aop:aspectj-autoproxy/>
      	<context:annotation-config/>
      	
      	<context:load-time-weaver aspectj-weaving="on" weaver-class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/>
      	
      	<bean id="coreLogAspect" class="be.elitetagger.core.aspect.CoreLogAspect"/>
      </beans>
      aop xml in meta-inf folder:

      HTML Code:
      <?xml version="1.0" encoding="UTF-8"?>
      
      <!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
      
      <aspectj>
      	<weaver options="-showWeaveInfo -verbose -Xlint:ignore">
      		<include within="be.elitetagger.core..*"/>
      	</weaver>
      	<aspects>
      		<aspect name="be.elitetagger.core.aspect.CoreLogAspect"/>
      	</aspects>
      </aspectj>
      After this configuration, it seems to be working !

      I also had to add -Xlint:ignore as param for weaver because I have a transactional annotation myself and the weaver gave errors there...

      Enjoy !

      PS: Spring really ROX ! Never thought that a Framework would be so awesome ! ;D Very portable, love it !
      Last edited by Kristof303; Sep 5th, 2012, 06:38 PM.

      Comment


      • #4
        Originally posted by Enrico Pizzi View Post
        No, you can't use Spring AOP without using Spring DI because Spring AOP only works on beans defined in Spring, which Spring knows of and manages. However you can use AOP without Spring, just use standalone AspectJ: write your aspects in the AspectJ language, and use the AspectJ compiler to compile your code.
        yes you can I don't use spring at all for DI but now only use Spring AOP and make my beans aware, check my solution

        You probably think its weird but I have a core module of my project that will soon be extracted to act as an seperate project. I want to give opportunity to plug in Spring or AOP or security...
        Last edited by Kristof303; Sep 5th, 2012, 06:25 PM.

        Comment


        • #5
          yes you can I don't use spring at all for DI but now only use Spring AOP
          You're not using Spring AOP, you're using AspectJ configured through Spring. It's not the same thing, its worlds apart actually. Spring AOP would not require any code weaving (either by load time instrumentation or at compile time using the AspectJ compiler) because it works by using proxies. You would not need an aop.xml which is clearly AspectJ stuff.

          If the difference is not clear, I urge you to refer to the relevant chapter in the reference documentation.

          Comment


          • #6
            I know there is a difference between Spring AOP and aspects.. I tried to do it in different ways like Maven AspectJ plugin and Eclipse ADJT plugin (but it sux).. So I had to find other ways to achieve it.. And Spring was my first option to try out...

            Still, I had hoped that someone gave me the idea that you could use Spring for configuring aspects like you told.. :-)

            I will in the future also use Spring DI so therefore I wanted it to let it work through Spring so I don't have a lot of worries later on...

            Thanks anyways.

            Cheers

            Comment

            Working...
            X