Ứng dụng thực tế của @DeclareParents trong Spring AOP

@DeclareParents

Annotation này được dùng để giới thiệu các interface mới cho các lớp hiện có tại runtime. Sau nhiều nghiên cứu, mình đã tìm ra một cách ứng dụng khá thực tế và muốn chia sẻ với mọi người. Bài viết này sử dụng cấu hình Java cho Spring, các bạn có thể tham khảo.

Để hiểu ứng dụng cơ bản, tham khảo tại (https://blog.csdn.net/u010502101/article/details/76944753)

Dưới đây là thiết kế mình đã áp dụng:

Giao diện ConTho

public interface ConTho {

    public void no(String noi);
    public void setTen(String ten);
    public String getTen();
}

Lớp triển khai giao diện ConTho

@Component
public class ConThoThucTe implements ConTho{

    private String  ten;

    public void no(String noi)
    {
        System.out.println(getTen()+" nói "+noi);
    }

    public String getTen() {
        return ten;
    }

    public void setTen(String ten) {
        this.ten = ten;
    }
}

Giao diện ConTho Đỏ

public interface ConThoDo extends ConTho {
    public void nhay();

}

Lớp triển khai giao diện ConTho Đỏ

public class ConThoDoThucTe extends ConThoThucTe implements ConThoDo {



    public void nhay()
    {
        System.out.println(getTen()+" nhay nhay");
    }

    @Override
    public void no(String noi) {
        super.noi(noi);
    }

    @Override
    public void setTen(String ten) {
        super.setTen(ten);
    }

    @Override
    public String getTen() {
        return super.getTen();
    }
}

Cấu hình Spring bằng Java

/**
 * Lớp cấu hình Spring
 * Tương tự như việc load file xml
 *
 * @ContextConfiguration(classes = SpringConfig.class) Sử dụng annotation này trên class để load
 */
@Configuration//Đánh dấu đây là một lớp cấu hình
@EnableAspectJAutoProxy//Bật các annotation liên quan đến AOP
@ComponentScan(basePackages = {"com.vn.aop","com.vn.bean", "com.vn.impl"})
public class SpringConfig {

    

    @Bean(name="conThoExAop")
    public ConThoExAop conThoExAop() {
        return  new ConThoExAop();
    }

}

Cấu hình giới thiệu增强

/**
 *  Cấu hình giới thiệu增强
 */
@Aspect
public class ConThoExAop {

    @DeclareParents(value = "com.vn.impl.ConThoThucTe+", defaultImpl = ConThoDoThucTe.class)
    public ConThoDo conThoDo;
}

Mã gọi thực thi

/**
 * Sử dụng cách tự động load của Spring
 */
@ContextConfiguration(classes = SpringConfig.class)
public class MainAutoUtil extends SpringTestBase {

    @Autowired
    private ConTho conTho;

    @Test
    public void test() {

        conTho.setTen("Bạch Tho");
        conTho.no("Tôi là một con thỏ buồn");

        ConThoDo conThoDo=(ConThoDo)conTho;
        conThoDo.no("Tôi là một con thỏ vui vẻ");
        conThoDo.nhay();
    }<br></br><br></br>

Kết quả thực thi

Bạch Tho nói Tôi là một con thỏ buồn
Bạch Tho nói Tôi là một con thỏ vui vẻ
Bạch Tho nhay nhay

Mình cũng xin đính kèm cấu hình test của Spring

/**
 * Lớp cấu hình unit test
 */
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringTestBase extends AbstractJUnit4SpringContextTests {

}

Trên đây là mã nguồn mình đã triển khai

Trong trường hợp giao diện và lớp triển khai là một file jar từ hệ thống khác, bạn không thể truy cập mã nguồn, chỉ có thể kế thừa để nhận đối tượng.

Trong quá trình ứng dụng thực tế, bạn muốn tăng cường động đối tượng từ các hệ thống khác, ví dụ như ConTho Đỏ, là phiên bản nâng cấp của ConTho, có phương thức mở rộng nhay mà ConTho thông thường không có. Khi đó, bạn có thể ép kiểu đối tượng ConTho thành ConThoDo, giúp đối tượng ConTho có thêm phương thức mở rộng nhay, thuận tiện cho việc phát triển sau này.

Như vậy, lớp con có thể trỏ đến đối tượng lớp cha.

Mình mới học Spring nên có gì sai sót mong mọi người chỉ bảo. Cảm ơn các bạn đã quan tâm.

Thẻ: Spring AOP @DeclareParents aspectj Java Configuration

Đăng vào ngày 5 tháng 6 lúc 17:41