最近一直在看Spring框架文档,也对@DeclareParents
注释有了初步的了解,所以这篇文章仅提供入门参考。
通过注释@DeclareParents
,可以提供强大的代理功能。那么如何理解这种代理功能呢?如下图所示,B其实就是代理类,用于增强类A的能力(如添加方法实现)。这里可能会有疑惑:为什么不在A类中直接添加想要的功能呢?
在面向切面编程(AOP)时,为了避免侵入性,减少对业务代码的结构影响,同时也遵循面向切面编程的思想,所以通过代理来增强被代理类的功能是更好的选择。面向对象编程的一个目的是,将非业务代码从业务代码中分离出来,那么应该通过代理实现增强被代理类,而不是将非业务代码(这里指通过代理增强被代理类的功能代码)写进业务代码模块中。
通过以下案例,可以更好的理解。
package com.springboot.demo.entity;
public interface ProxyClass {
void print();
}
package com.springboot.demo.entity;
public class ProxyClassImpl implements ProxyClass {
public void print() {
System.out.println("this is ProxyClass");
}
}
package com.springboot.demo.entity;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class Person {
public void out(){
System.out.println("hello");
}
}
使用注释@DeclareParents
建立代理关系
package com.springboot.demo.aop;
import com.springboot.demo.entity.ProxyClass;
import com.springboot.demo.entity.ProxyClassImpl;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.DeclareParents;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class AopExample {
@DeclareParents(value = "com.springboot.demo.entity.Person",defaultImpl = ProxyClassImpl.class)
ProxyClass proxy;
}
上面代码说明,Person
类是被ProxyClassImpl
类代理,实际上两者互为代理,可以通过测试验证
package com.springboot.demo;
import com.springboot.demo.entity.Person;
import com.springboot.demo.entity.ProxyClass;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class DemoApplicationTests {
@Autowired
Person person;
@Autowired
ProxyClass proxyClass2;
@Test
void contextLoads() {
ProxyClass proxyClass = (ProxyClass) person;
proxyClass.print();
Person person2 = (Person) proxyClass2;
person2.out();
}
}
通过注释@Autowired
,注入Person
类和 ProxyClass
接口的实例,然后对两者进行强制转型,然后调用转型后的类的方法,看看是否会报错。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9h5Umcja-1583059597194)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200301165029444.png)]
Person类和
ProxyClass`接口的实例,然后对两者进行强制转型,然后调用转型后的类的方法,看看是否会报错。
[外链图片转存中…(img-9h5Umcja-1583059597194)]
通过结果,可以看到代理与被代理的关系是相互的,因为你可以通过代理类去得到被代理类的能力,反过来也成立。