@DeclareParents fail to introduce new method

everybody, I am a beginner in Spring and I am encountering some problems with @DeclareParents. I follow the instructions in Spring In Action but I fail to realize the introduction.

Here are my codes. I first define Interface performance

public interface Performance {
    void perform();
}

and then implement the interface.

@Component
public class OnePerformance implements Performance {
    @Autowired
    public OnePerformance(){
    }

    public void perform() {
        System.out.println("The Band is performing....");
    }

}

I want to introduce method void performEncore() into Performance. So I define the Interface,

public interface Encoreable {
    void performEncore();
}

implement it,

@Aspect
public class DefaultEncoreable implements Encoreable{
    public void performEncore() {
        System.out.println("performEncore");
    }
}

and introduce it,

@Aspect
@Component
public class EncoreableIntroduction {            
    @DeclareParents(value="Performance+",
        , defaultImpl=DefaultEncoreable.class)
     public static Encoreable encoreable;
}

I use autoconfiguration,

@Configuration
@EnableAspectJAutoProxy
@ComponentScan
public class ConcertConfig {
}

However, when testing, I fail to introduce method void performEncore().

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes= ConcertConfig.class)
public class OnePerformanceTest {
    @Autowired
    private Performance performance;

    @Test
    public void perform() throws Exception {
        performance.perform();
}}

Junit4 Test Class

And I also enabled AspectJ Support Plugins. My IntelliJ IDEA PLUGIN Settings

I have read the book and several blogs carefully but I still can not find the cause. So what may be the cause of this problem? Thanks in advance.

Answer

Thanks for M. Deinum, NewUser and Wim Deblauwe. With their help, I finally figured out the problem. The previous JUnit4 class is not correct.

The proper solution to solve this problem is to cast Performance into Encoreable, and then call the performEncore() method.

The code is as follow:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes= ConcertConfig.class)
public class OnePerformanceTest {
    @Autowired
    private Performance performance;

    @Test
    public void perform() throws Exception {
        Encoreable encoreable = (Encoreable)(performance);
        encoreable.performEncore();
    }
}

screen capture of the final result

Leave a Reply

Your email address will not be published. Required fields are marked *