I've been trying to get this to work for a few days and have been failing miserably at it. I cannot seem to get my class cast properly to an Introduced interface. I'm using Spring 3.0.5.
Does anyone have a complete working example of a project that uses @DeclareParents? Or the XML equivalent? I have found a bunch of snippets on the web, but haven't had success in getting those to work either.
This is my first time trying Introductions, but am having a lot of difficulty getting this to work. I've read through the Spring docs and the AspectJ docs as well as well as the forums but still cannot get this to work. I thought created the classes/interfaces correctly, but when I try to cast the Advised object to the interface, I get a cast error.
Target:
@Entity @Table(name = "item") public class Item implements java.io.Serializable { private long id; private Integer mainType; private Integer subType; private String brandName; private String itemName; private Date releaseDate; private Date retireDate; private String fileName; private String thumbnailName; private String dimension; private boolean active; private boolean unlocked; private Integer unlockCost; private boolean owned; public Item() { } ... // bunch of getters and setters ... }
Interface:
public interface AbstractBaseEntity { /** * @return the customAttributes */ public Object getCustomAttribute(String name); /** * @param customAttributes the customAttributes to set */ public void setCustomAttribute(String name, Object value); }
Implementation:
public class AbstractBaseEntityImpl implements AbstractBaseEntity { /** * Map of custom attributes that can be mapped for the specific entity */ @Transient protected Map customAttributes = new ConcurrentHashMap(); /** * @return the customAttributes */ public Object getCustomAttribute( String name ) { return customAttributes.get(name); } /** * @param customAttributes the customAttributes to set */ public void setCustomAttribute(String name, Object value) { this.customAttributes.put(name, value); } }
Aspect:
@DeclareParents(value="com.fwl.domain.model.*+", defaultImpl=AbstractBaseEntityImpl.class) public AbstractBaseEntity mixin;
However, when I pass my introduced object to a method as an Object parameter, checking if it is an instanceof AbstractBaseEntity, it returns false.
public void localize(Object entity, Locale locale) { List cachedFields; if (entity == null) // do nothing return; // check if the entity is already localized if( entity instanceof AbstractBaseEntity) // already localized so nothing to do return; ... ... }
Is there anyway to ensure that the introduction is being done properly? Anyway to determine why I cannot cast it as an AbstractBaseEntity?
Any help would be greatly appreciated.
Thanks,
Eric
Where to use Spring Aspect Oriented Programming. Some of the cases where AOP is frequently used: To provide declarative enterprise services. For example, as declarative transaction management. It allows users for implementing custom aspects.
As far as performance is concerned, compile-time weaving is much faster than runtime weaving. Spring AOP is a proxy-based framework, so there is the creation of proxies at the time of application startup. Also, there are a few more method invocations per aspect, which affects the performance negatively.
For using Spring AOP in Spring beans, we need to do the following: Declare AOP namespace like xmlns:aop=“https://www.springframework.org/schema/aop” Add aop:aspectj-autoproxy element to enable Spring AspectJ support with auto proxy at runtime.
I have working example, but I know that the question is very old.
Basic Interface:
package pl.beans;
public interface Performance {
public void perform();
}
implementation of Performance:
package pl.beans;
import java.util.Random;
import org.springframework.stereotype.Component;
@Component
public class Actor implements Performance {
private static final String WHO = "Actor: ";
@Override
public void perform() {
System.out.println(WHO+"Making some strange things on scene");
int result = new Random().nextInt(5);
if(result == 0) {
throw new IllegalArgumentException(WHO+"Actor falsified");
}
}
}
New interface:
package pl.introduction;
public interface Crazy {
public void doSomeCrazyThings();
}
Implementation of new interface:
package pl.introduction;
public class CrazyActor implements Crazy {
@Override
public void doSomeCrazyThings() {
System.out.println("Ługabuga oooo 'Performer goes crazy!'");
}
}
Aspect:
package pl.introduction;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;
@Aspect
public class CrazyIntroducer {
@DeclareParents(value="pl.beans.Performance+", defaultImpl=pl.introduction.CrazyActor.class)
public static Crazy shoutable;
}
JavaConfig:
package pl.introduction;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import pl.beans.Actor;
import pl.beans.Performance;
@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class Config {
@Bean
public CrazyIntroducer introducer () {
return new CrazyIntroducer();
}
@Bean
public Performance performance() {
return new Actor();
}
}
And test which shows that introduction working:
package pl.introduction;
import static org.junit.Assert.assertTrue;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import pl.beans.Performance;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = pl.introduction.Config.class)
public class IntroductionTest {
@Autowired
private Performance performance;
@Test
public void shoutTest() {
try {
performance.perform();
} catch (IllegalArgumentException e) {
System.out.println(e);
}
assertTrue(performance instanceof Crazy);
((Crazy) performance).doSomeCrazyThings();
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With