c. Cglib代理
    1)静态代理和JDK代理模式都要求目标对象是实现一个接口,但是有时候目标对象只是一个单独的对象,并没有实现任何的接口,这个时候可使用目标对象子类来实现代理-这就是Cglib代理
    2) Cglib代理也叫作子类代理,它是在内存中构建一个子类对象从而实现对目标对象功能扩展,有些书也将Cglib代理归属到动态代理。
    3) Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口.它广泛的被许多AOP的框架使用,例如Spring AOP,实现方法拦截。
    4)在AOP编程中如何选择代理模式:
    1、目标对象需要实现接口,用JDK代理目标
    2、对象不需要实现接口,用Cglib代理。
    5) Cglib包的底层是通过使用字节码处理框架ASM来转换字节码并生成新的类。

    CGLIB原理:动态生成一个要代理类的子类,子类重写要代理的类的所有不是final的方法。在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。它比使用java反射的JDK动态代理要快。
    缺点:无法处理final方法

    目标类:

    1. /**
    2. * 目标类
    3. */
    4. public class CglibDao {
    5. public void getMethod(){
    6. System.out.println("需要增强方法的主体内容");
    7. }
    8. }

    创建代理类的类

    1. /**
    2. * @author shizi 2022/1/25
    3. * 创建代理类的类
    4. */
    5. public class CreateCglibProxy implements MethodInterceptor {
    6. /**
    7. * 聚合目标类
    8. */
    9. private Object object;
    10. public CreateCglibProxy(Object object) {
    11. this.object = object;
    12. }
    13. /**
    14. * 获取代理对象
    15. * @return
    16. */
    17. public Object getCglibProxy(){
    18. //创建一个cglib对象
    19. Enhancer enhancer = new Enhancer();
    20. //设置代理对象的父类即目标类
    21. enhancer.setSuperclass(object.getClass());
    22. //设置回调函数
    23. enhancer.setCallback(this);
    24. //创建代理类对象并返回
    25. return enhancer.create();
    26. }
    27. /**
    28. * 用于增强目标类的方法
    29. */
    30. @Override
    31. public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
    32. System.out.println("cglib代理开始-----------");
    33. Object invoke = method.invoke(object, objects);
    34. System.out.println("cglib代理结束-----------");
    35. return invoke;
    36. }
    37. }

    测试

    1. public class Test {
    2. public static void main(String[] args) {
    3. //创建目标对象
    4. CglibDao cglib = new CglibDao();
    5. CreateCglibProxy createCglibProxy = new CreateCglibProxy(cglib);
    6. //获取代理对象
    7. CglibDao cglibProxy = (CglibDao)createCglibProxy.getCglibProxy();
    8. cglibProxy.getMethod();
    9. }
    10. }

    总结JDK动态代理和CGLIB动态代理:
    相同点:都是在内存中去创建代理对象,功能也是一样的,都是完成对目标方法的增强
    不同点:
    jdk代理:要求目标类必须实现一个接口,内存中创建出来的代理类也会实现相同的接口
    cglib代理:目标类不用实现接口,可以只是一个普通的类,在内存中创建出的代理类是
    目标类的子类
    总结:动态代理实际上都是用于增强目标方法,如果需要增强的类实现了接口,我们需要采用
    JDK代理,如果没有实现接口,我们采用Cglib代理!!

    动态代理在以后开发中的作用:
    SpringAop(面向切面编程:底层就是通过代理模式实现的):
    模块1:
    模块2:
    模块3:
    假设某项目有很多模块,每个模块封装了不同业务逻辑,我们以后使用框架进行开发,目的可以提高开发效率,可以让开发人员只去关注核心业务,不去关注一些非核心的业务!!!

    1. 提一个需求:希望每个模块都能完成日志的收集,当任意一个模块的代码发生了异常,这个时候希望整理成日志文档,方便开发人员排错!
    2. 注意:日志收集的代码不属于核心业务,日志收集的代码是每个模块都需要的
    3. SpringAop可以完成对核心模块的增强:日志收集的代码(就是需要对每个模块增强的部分)
    4. 增强步骤:
    5. 1、获取每个模块的目标方法<br /> 2、配置springAop的切面=====》切面(指的就是增强的过程)
    6. 切面:<br /> spring会去校验核心模块中的核心类是否实现了接口,如果实现了,在底层使用jdk代理来完成<br /> 如果没有实现,用cglib代理来完成!!
    7. 核心类实现了接口 invoke
    8. 日志收集的代码1
    9. 通过反射机制调用目标方法
    10. 日志收集的代码2<br /> }<br /> 所以说,通过这种方式,可以让非核心代码脱离核心模块,而且方便维护,易于管理!!!

    d.工厂模式
    简单工厂模式:https://blog.csdn.net/ShuSheng0007/article/details/86634864
    核心就是通过一个工厂方法根据不同的条件生产同一类型的产品
    抽象工厂模式:https://blog.csdn.net/ShuSheng0007/article/details/86644481
    核心在于一个工厂方法生产一个品牌家族的系列产品
    工厂方法模式:https://blog.csdn.net/ShuSheng0007/article/details/86636494
    核心仍旧是如何创建同一类型产品(都实现同一个接口)的问题,只不过是通过为每一种要生产的产品配备一个工厂,就是说每个工厂只生产一种特定的产品。

    简单工厂中创建产品使用反射:
    简单工厂类:

    1. public interface Factory {
    2. /**
    3. * 制作手机的方法
    4. */
    5. Phone makePhone(String className);
    6. }

    工厂类:

    1. /**
    2. * 生产手机:通过简单工厂模式来写这个类
    3. */
    4. public class PhoneFactory implements Factory {
    5. /**
    6. * 生产手机的
    7. * @param className
    8. * @return
    9. */
    10. @Override
    11. public Phone makePhone(String className) {
    12. if (className != null){
    13. try {
    14. //获取字节码对象
    15. Class aClass = Class.forName(className);
    16. //通过发射机制来创建手机手机实例
    17. Object obj = aClass.newInstance();
    18. if (obj instanceof Phone){
    19. return (Phone) obj;
    20. }
    21. } catch (ClassNotFoundException e) {
    22. e.printStackTrace();
    23. } catch (IllegalAccessException e) {
    24. e.printStackTrace();
    25. } catch (InstantiationException e) {
    26. e.printStackTrace();
    27. }
    28. }
    29. return null;
    30. }
    31. }

    使用工厂生产产品:

    1. /**
    2. *
    3. * 需求:通过工厂获取手机实例
    4. */
    5. public class FactoryTest {
    6. public static void main(String[] args) {
    7. //创建工厂实例
    8. Factory factory = new PhoneFactory();
    9. //获取华为实例
    10. Phone phone = factory.makePhone("com.jy.factory.phone.HuaWei");
    11. phone.make();
    12. //获取苹果实例
    13. Phone phone2 = factory.makePhone("com.jy.factory.phone.Iphone");
    14. phone2.make();
    15. }
    16. }