@DeclareParents的作用
@DeclareParents是SpringAOP提供的一种功能,允许我们在代理目标类上增加新的行为,即新的方法。
例子:
先有代理类:ICar接口
package com.liuquanju.aop.dao.car;
/**
* @Description 汽车接口
* @Date 下午3:50 2022/5/22
**/
public interface ICar {
/**
* @Author yingjie.liu
* @Description 轮子
* @Date 下午3:51 2022/5/22
**/
void wheel();
/**
* @Author yingjie.liu
* @Description 车灯
* @Date 下午3:52 2022/5/22
**/
void light();
}
ICar接口实现类:Autotruck
package com.liuquanju.aop.dao.car;
import org.springframework.stereotype.Service;
/**
* @program: liuquanju-parent
* @ClassName Autotruck
* @description:
* @create: 2022-05-22 15:53
* @Version 1.0
**/
@Service
public class Autotruck implements ICar{
@Override
public void wheel() {
System.out.println("this is autotruck wheel ...");
}
@Override
public void light() {
System.out.println("this is autotruck light ...");
}
}
ICar接口实现类:Autotruck
package com.liuquanju.aop.dao.car;
import org.springframework.stereotype.Service;
/**
* @program: liuquanju-parent
* @ClassName SedanCar
* @description:
* @create: 2022-05-22 15:56
* @Version 1.0
**/
@Service
public class SedanCar implements ICar {
@Override
public void wheel() {
System.out.println("this is SedanCar wheel ...");
}
@Override
public void light() {
System.out.println("this is SedanCar light ...");
}
}
假如我们有如下需求:
- ICar接口有n多个实现类,每个类中有n个方法(行为);
- 我们需要在ICar的众多实现类中增加一个方法(行为),但又不希望每个实现类都去增加一个新的方法,或者新建类继承原类;
使用@declareParents注解实现
如:
public interface IDriver {
/**
* @Author yingjie.liu
* @Description TODO
* @Date 下午4:03 2022/5/22
**/
void sex();
}
IDriver实现类:
public class WomanDriver implements IDriver{
@Override
public void sex() {
System.out.println("the woman driver...");
}
}
我们将WomanDriver中的sex()方法引入到上边的SedanCar和Autotruck中
- 配置类:
@Configuration
@ComponentScan(value = "com.liuquanju.aop")
// 如果proxyTargetClass设置为true,则为强制使用cglib代理,spring默认使用jdk动态代理
@EnableAspectJAutoProxy(proxyTargetClass = false)
public class MyConfig {
}
- 新建切面类
@Component
@Aspect
public class CarAspectj {
/**
* @Description @DeclareParents 的结构,由三部分组成:
* 1. value 属性指定了哪种类型的bean要引入新的接口行为,本例子中是ICar,并在起后接着 "+" ,代表ICar下的所有子类型,非ICar自身。
* 2. defaultImpl属性指定了提供新的行为的接口的实现类
* 3. @DeclareParents 标注的类标识需要引入的新提供的行为接口,如例子中IDriver接口,且defaultImpl属性的类(WomanDriver)是IDriver的实现类
* @Date 下午5:31 2022/5/22
**/
@DeclareParents(value = "com.liuquanju.aop.dao.car.ICar+", defaultImpl = WomanDriver.class)
public IDriver iDriver;
}
- 测试类:
public class CarAspectjTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
ICar sedanCar = (ICar) applicationContext.getBean("sedanCar");
sedanCar.wheel();
IDriver womanDriver = (IDriver) sedanCar;
womanDriver.sex();
}
}
运行Debug,会发现:sedanCar的代理实现了两个接口,一个是我们实现的ICar接口,一个是IDriver接口,这样便实现了将新的行为引入需要新增新行为的类中
欢迎各位大佬指正