Results 1 to 4 of 4

Thread: Introduction on domain objects on business method?

  1. #1

    Smile Introduction on domain objects on business method?

    I need to introduce new methods on domain objects passed to business methods.

    If yes how could I do this on the following sample? I am specifically looking for the joinpoint

    Code:
    @Aspect
    public class UsageTracking {
    
      @DeclareParents(value="com.xzy.myapp.domain.*+",
                      defaultImpl=DefaultUsageTracked.class)
      public static UsageTracked mixin;
      
      @Before("com.xyz.myapp.SystemArchitecture.businessService() && <I NEED SOMETHING HERE>")
      public void recordUsage(UsageTracked usageTracked) {
        usageTracked.incrementUseCount();
        
       //IS THERE ANY CLEAN WHY TO GET ACCESS OF TARGET OBJECT? 
      // DomainObject do = (DomainObject) usageTracked;
      }
      
    }

  2. #2
    Join Date
    Nov 2007
    Posts
    420

    Default

    Quote Originally Posted by SpringingSpringles View Post
    I need to introduce new methods on domain objects passed to business methods.

    If yes how could I do this on the following sample? I am specifically looking for the joinpoint

    Code:
    @Aspect
    public class UsageTracking {
    
      @DeclareParents(value="com.xzy.myapp.domain.*+",
                      defaultImpl=DefaultUsageTracked.class)
      public static UsageTracked mixin;
      
      @Before("com.xyz.myapp.SystemArchitecture.businessService() && <I NEED SOMETHING HERE>")
      public void recordUsage(UsageTracked usageTracked) {
        usageTracked.incrementUseCount();
        
       //IS THERE ANY CLEAN WHY TO GET ACCESS OF TARGET OBJECT? 
      // DomainObject do = (DomainObject) usageTracked;
      }
      
    }
    You can't introduce new methods on domain objects with Spring AOP. If you want to advise domain objects you have to use AspectJ and weave in your new methods, can't be done with Spring AOP.

  3. #3

    Default

    Quote Originally Posted by bdangubic View Post
    You can't introduce new methods on domain objects with Spring AOP. If you want to advise domain objects you have to use AspectJ and weave in your new methods, can't be done with Spring AOP.
    Thank you for answer. Can you point to some example with aspectj on this please?

  4. #4

    Smile

    Quote Originally Posted by SpringingSpringles View Post
    Thank you for answer. Can you point to some example with aspectj on this please?
    I got it with aspectj and spring. Here is the code for anyone interested.

    DOMAIN OBJECTS:
    Code:
    package com.sample.domain;
    
    public class Sample {
    
    	private Long id;
    	private String type;
    	private String description;
    
    	public String getType() {
    		return type;
    	}
    
    	public void setType(String type) {
    		this.type = type;
    	}
    
    	public String getDescription() {
    		return description;
    	}
    
    	public void setDescription(String description) {
    		this.description = description;
    	}
    
    	public Long getId() {
    		return id;
    	}
    
    	public void setId(Long id) {
    		this.id = id;
    	}
    
    }
    SERVICES:

    Code:
    package com.sample.service;
    
    import java.util.List;
    
    import com.sample.domain.Sample;
    
    
    public interface SampleService {
    
    	public Sample saveSample(Sample sample);
    
    	public Sample addSample(Sample sample);
    
    	public Sample getRandomSample();
    
    	public List<Sample> saveSamples(List<Sample> samples);
    
    	public List<Sample> getRandomSamples();
    }
    Code:
    package com.sample.service.impl;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    
    import org.apache.commons.lang.RandomStringUtils;
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.stereotype.Service;
    
    import com.sample.domain.Sample;
    import com.sample.service.SampleService;
    
    @Service
    public class SampleServiceImpl implements SampleService {
    
    	private static Log log = LogFactory.getLog(SampleServiceImpl.class);
    
    	private HashMap<Long, Sample> store = new HashMap<Long, Sample>();
    
    	protected Sample saveToStore(Sample sample) {
    		if (store.containsKey(sample.getId())) {
    			store.put(sample.getId(), sample);
    			log.info("Sample " + sample.getId() + " saved!");
    		} else {
    			log.warn("Sample " + sample.getId() + " not found in store!");
    		}
    		return sample;
    	}
    
    	protected Sample getSample(Long id) {
    		return store.get(id);
    	}
    
    	protected Sample getOrGenerateSample() {
    		long id = (long) (Math.random() * 100);
    		Sample sample = getSample(id);
    		if (sample == null) {
    			sample = new Sample();
    			sample.setId(id);
    			sample.setType(RandomStringUtils.randomAlphanumeric((int) id));
    			sample.setDescription(RandomStringUtils.randomAlphabetic((int) id));
    			store.put(id, sample);
    		}
    		return sample;
    	}
    
    	public Sample addSample(Sample sample) {
    		log.info("target: " + sample.getClass());
    		return saveToStore(sample);
    	}
    
    	public Sample getRandomSample() {
    		return getOrGenerateSample();
    	}
    
    	public List<Sample> getRandomSamples() {
    		int count = (int) (Math.random() * 20);
    		if (count == 0) {
    			count++;
    		}
    		;
    		ArrayList<Sample> samples = new ArrayList<Sample>(count);
    		for (int i = 0; i < count; i++) {
    			samples.add(getOrGenerateSample());
    		}
    		return samples;
    	}
    
    	public Sample saveSample(Sample sample) {
    		log.info("target: " + sample.getClass());
    		return saveToStore(sample);
    	}
    
    	public List<Sample> saveSamples(List<Sample> samples) {
    		for (Sample sample : samples) {
    			saveToStore(sample);
    		}
    		return samples;
    	}
    
    }
    ASPECTS:
    Code:
    package com.sample.aspect;
    
    public interface UsageTracked {
    
    	public void incrementUseCount();
    
    	public long getUseCount();
    }
    Code:
    package com.sample.aspect;
    
    
    public class DefaultUsageTracked implements UsageTracked {
    
    	private long useCount = 0;
    
    	public long getUseCount() {
    		return useCount;
    	}
    
    	public void incrementUseCount() {
    		useCount++;
    	}
    
    }
    Code:
    package com.sample.aspect;
    
    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.aspectj.lang.annotation.Aspect;
    import org.aspectj.lang.annotation.Before;
    import org.aspectj.lang.annotation.DeclareParents;
    
    import com.sample.domain.Sample;
    
    @Aspect
    public class UsageTrackingIntroduction {
    
    	private Log log = LogFactory.getLog(UsageTrackingIntroduction.class);
    
    	@DeclareParents(value = "com.sample.domain.*", defaultImpl = DefaultUsageTracked.class)
    	private static UsageTracked usageTracked;
    
    	@Before("execution(public * com.sample.service.SampleService.*(..)) && args(usageTracked)")
    	public void recordUsage(UsageTracked usageTracked) {
    		usageTracked.incrementUseCount();
    		log.info("Use count: " + usageTracked.getUseCount());
    		log.info("target: " + usageTracked.getClass());
    		if (usageTracked instanceof Sample) {
    			Sample sample = (Sample) usageTracked;
    			log.info("Hooray!");
    		}
    	}
    }
    MAIN :
    Code:
    package com.sample;
    
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import com.sample.domain.Sample;
    import com.sample.service.SampleService;
    
    
    public class AopTestsMain {
    
    	public static void main(String[] args) {
    		ApplicationContext ctx = new ClassPathXmlApplicationContext(
    				"AopTests-context.xml");
    		SampleService sampleService = (SampleService) ctx
    				.getBean("sampleServiceImpl");
    		Sample sample = sampleService.getRandomSample();
    		sample.setDescription("I am new");
    		sample.setType("unique?");
    
    		sampleService.saveSample(sample);
    	}
    }
    META-INF/aop.xml
    Code:
    <!DOCTYPE aspectj PUBLIC
            "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
    <aspectj>
    
    	<weaver>
    		<!-- only weave classes in our application-specific packages -->
    		<include within="com.sample.domain.*" />
    		<include within="com.sample.aspect.*" />
    		<include within="com.sample.service.impl.*" />
    	</weaver>
    
    	<aspects>
    		<!-- weave in just this aspect -->
    		<!-- <aspect name="com.sample.ProfilingAspect" /> -->
    		<aspect name="com.sample.aspect.UsageTrackingIntroduction" />
    	</aspects>
    
    </aspectj>

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •