动态代理对象的属性注入

下面会分别对Jdk和Cglib两种类型的动态代理的对象进行分析

1.Cglib

1> 直接通过反射创建代理对象

  User user=new User("zyz",123);
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(user.getClass());
        enhancer.setInterfaces(user.getClass().getInterfaces());
        enhancer.setCallback(new NoOp() {
            @Override
            public int hashCode() {
                return super.hashCode();
            }
        });

        User u=(User) enhancer.create();
        System.out.println(u);
        BeanUtil.setFieldValue(u,"name","mzd");
        BeanUtil.setFieldValue(u,"age",456);
        System.out.println(u);
        u.name="cyq";
        System.out.println(u);


// res:
User{name='null', age=0}
User{name='mzd', age=456}
User{name='cyq', age=456}

     没有指定代理的对象时,直接修改和通过强制注入都是可以修改代理对象的属性值的

2> 代理某个对象

  User user=new User("zyz",123);
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(user.getClass());
        enhancer.setInterfaces(user.getClass().getInterfaces());


        enhancer.setCallback(new MethodInterceptor() {
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {

             return methodProxy.invoke(user,objects);
            }
        });
        User u=(User) enhancer.create();
        System.out.println(u);
        BeanUtil.setFieldValue(u,"name","mzd");
        BeanUtil.setFieldValue(u,"age",456);
        System.out.println("****");
        System.out.println(u);
        BeanUtil.setFieldValue(user,"name","mzd");
        System.out.println("****");
        System.out.println(user);
        System.out.println(  u.getClass().getFields().length);
        for (Field field:u.getClass().getFields())
        {
            System.out.println(field.getName());
        }
        System.out.println("****");

        u.name="qaz";
        System.out.println(u);
        System.out.println("****");


// res:

User{name='zyz', age=123}
****
User{name='zyz', age=123}
****
User{name='mzd', age=123}
3
CGLIB$FACTORY_DATA
name
age
****
User{name='mzd', age=123}
****

Process finished with exit code 0

     由结果可见,创建了一个user对象,用cglib来代理这个类,直接改变代理类的属性值,是不起作用的,虽然修改代理类u的属性,但是输出u结果还是输出的被代理对象user本身的属性值,我猜测是因为User是它的父类,由于编译看左边的缘故所以优先输出User对象的属性? 这点我也存在疑惑。总之,若指定了代理的对象,直接修改生成代理对象的属性是不起作用的。

    但是直接修改被代理类的值,这时候代理类的值是变化的

2.JDK动态代理

   1>直接通过反射创建

        User user=new User();
        User user1 = user.getClass().newInstance();
        BeanUtil.setFieldValue(user1,"name","mzd");
        BeanUtil.setFieldValue(user1,"age",456);
        System.out.println(user1);
        user1.name="cyq";
        System.out.println(user1);

    // res:
       User{name='mzd', age=456}
       User{name='cyq', age=456}

          反射创建可以修改属性的值

2>

     User user=new User("zyz",1321);
        User user1 = user.getClass().newInstance();


        UserService1 u = (UserService1) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(), user.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                return method.invoke(user, args);
            }
        });
        System.out.println(u);
        BeanUtil.setFieldValue(u,"name","mzd");
        BeanUtil.setFieldValue(u,"age",456);
        System.out.println("****");
        System.out.println(u);
        BeanUtil.setFieldValue(user,"name","mzd");
        System.out.println("****");
        System.out.println(user);
        System.out.println(  u.getClass().getFields().length);
        for (Field field:u.getClass().getFields())
        {
            System.out.println(field.getName());
        }

JDK动态代理更无法更改属性,因为jdk动态代理创建的对象必须用接口接收

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1 Spring基本特征 6 2 Spring的组成 6 2.1 Spring的jar包 6 2.2 Spring配置文件 7 2.3 Spring API 8 3 Spring基本功能详解 8 3.1 SpringIOC 8 3.2别名Alias 11 别名拓展: 11 3.3 Spring容器内部对象的创建 12 Spring容器内部对象创建拓展: 12 3.3.1使用类构造器实例化(默认无参数) 14 3.3.2使用静态工厂方法实例化(简单工厂模式) 14 3.3.3初始化(创建)bean时机 15 Lazy-init初始化bean的时机拓展: 15 3.4 Bean的作用域 16 Scope单例多例作用域拓展: 16 3.4.1 singleton(默认值) 16 3.4.2 prototype 17 3.4.3 Request 17 3.4.4 Session 18 3.4.5 Global session 18 3.4.6 指定Bean的初始化方法和销毁方法 18 Bean的初始化和销毁拓展: 18 Spring的IOC总结: 20 3.5 依赖注入(DI) 20 3.5.1 使用构造器注入 20 3.5.2 使用属性setting方法进行注入 21 3.5.3 装配list集合 22 3.5.4 装配set集合 22 3.5.5 装配map 22 3.5.6 装配Properties 23 3.6 注解注入 23 注解注入拓展: 23 3.6.1 @Autowired 26 3.6.2 @Qualifier 27 3.6.3 @Resource 27 3.6.4 @PostConstruct 28 3.6.5 @PreDestroy 28 注解注入拓展: 28 3.7扫描注入 30 注解扫描拓展: 32 Mvc用注解写: 34 Spring容器IOC和di的整个启动过程: 38 3.8 spring中的继承 38 拓展spring为类中的属性赋值: 40 小结: 47 面向接口编程: 47 4 面向切面编程 52 4.1 代理模式 52 代理模式拓展: 52 4.1.1 JDK动态代理 58 JDK动态代理拓展: 59 4.1.2 CGLIB做代理 66 CGLIB动态代理拓展: 68 4.1.3 Spring动态代理 71 4.2 AOP编程 71 4.2.1概念: 71 SpringAOP概念拓展: 73 之前实现了目标方法的动态调用,现在来实现切面的动态调用。 74 4.2.2 AOP实现的两种模式 78 4.2.2.1 xml形式 78 XML形式拓展: 81 异常通知处理例子: 91 不用spring异常通知,另一种处理异常 96 4.2.2.2Aop注解形式(了解) 99 注解注入拓展: 103 5 Spring数据库 106 5.1 Spring+JDBC 106 5.1.1 Jdbc编程特点 106 5.1.2引入DataSource 106 5.1.3 核心类JdbcTemplate 106 5.1.4 使用JdbcTemplate 106 5.1.5 继承JdbcDaoSupport 107 5.1.6 使用properties文件 107 5.1.7 RowMapper的使用 107 拓展: 108 DataSource注入的三种方式: 108 5.1.8声明式事务管理 116 5.1.8.1Spring的事务管理器 117 5.1.8.2Spring事务的传播属性 117 5.1.8.3Spring事务的隔离级别 117 拓展: 118 5.1.8.4以XML配置的 形式 119 拓展: 120 5.1.8.5以注解方式配置 125 拓展: 127 5.1.9使用CGLIB以XML形式配置事务 130 5.2 Spring+Hibernate 131 5.2.1 HibernateTemplate模板 131 5.2.2 声明式事务 131 配置XML文件 131 拓展: 132 注解形式: 137 拓展: 138 6 Struts2+spring+hibernate 141 6.1 需要添加的jar包 141 6.2 Spring融合web服务器 141 6.3 struts.xml文件 143 6.4 OpenInSessionView 143 拓展: 144 实例: 146
面试高级开发的期间整理的面试题目,记录我面试遇到过的spring题目以及答案 目录 spring ThreadLocal的底层对象; 为什么@Service和@Repository放到实现类上面而不是接口类上面; spring 三种注入(就是从spring容器中将bean放入对象属性值中) Spring下描述依赖关系@Resource, @Autowired和@Inject的区别与联系 Spring中BeanFactory和ApplicationContext的区别 谈谈Spring IOC的理解,原理与实现? bean的生命周期,详细看上面 SpringBoot自动装配的过程的原理: spring的缓存; spring是如何解决的循环依赖; BeanFactory和FactoryBean有什么区别; Spring中用到的设计模式; SPI 机制(Java SPI 实际上是“基于接口的编程+策略模式+配置文件”组合实现的动态加载机制), 很多地方有用到: AOP Spring的AOP的底层实现原理; 为什么jdk动态代理是必须是接口 两种动态代理的区别 AOP实现方式:aop注解或者xml配置;后来工具jar包aspects; aop的属性 事务 事务编码方式: 事务注意事项; 为什么同一个类A调用b方法事务,A方法一定要有事务(编码式的不用) @transaction多个数据源事务怎么指定数据源 传播特性有几种?7种; 某一个事务嵌套另一个事务的时候怎么办? REQUIRED_NEW和REQUIRED区别 Spring的事务是如何回滚的,实现原理; 抽象类和接口的区别,什么时候用抽象类什么时候用接口; StringBuilder和StringBuffer的区别 java值传递和引用传递
蚂蚁云客服机器人面试答案全文共6页,当前为第1页。蚂蚁云客服机器人面试答案全文共6页,当前为第1页。蚂蚁云客服机器人面试答案 蚂蚁云客服机器人面试答案全文共6页,当前为第1页。 蚂蚁云客服机器人面试答案全文共6页,当前为第1页。 1、自我介绍、自己做的项目和技术领域 开放题 2、项目中的监控:那个监控指标常见的有哪些? 答:CPU、内存、IO 等等。建议下载个nmon工具,里面有各个指标。 数据库:Mysql(缓存命中、索引、单条SQL性能、数据库线程数、数据池连接数) 中间件:1.消息2、负载均衡3、缓存(包括线程数、连接数、日志)。 网络: 吞吐量、吞吐率 应用: jvm内存、日志、Full GC频率 3、微服务涉及到的技术以及需要注意的问题有哪些? 4、注册中心你了解了哪些? 答:Consul 、Eureka、ZooKeeper 5、consul 的可靠性你了解吗? 6、consul 的机制你有没有具体深入过?有没有和其他的注册中心对比过? 7、项目用 Spring 比较多,有没有了解 Spring 的原理?AOP 和 IOC 的原理 答:(1). IoC(Inversion of Control)是指容器控制程序对象之间的关系,而不是传统实现中,由程序代码直接操控。控制权由应用代码中转到了外部容器,控制权的转移是所谓反转。 对于Spring而言,就是由Spring来控制对象的生命周期和对象之间的关系;IoC还有另外一个名字——"依赖注入(Dependency 蚂蚁云客服机器人面试答案全文共6页,当前为第2页。蚂蚁云客服机器人面试答案全文共6页,当前为第2页。Injection)"。从名字上理解,所谓依赖注入,即组件之间的依赖关系由容器在运行期决定,即由容器动态地将某种依赖关系注入到组件之中。 蚂蚁云客服机器人面试答案全文共6页,当前为第2页。 蚂蚁云客服机器人面试答案全文共6页,当前为第2页。 (2). 在Spring的工作方式中,所有的类都会在spring容器中登记,告诉spring这是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。 (3). 在系统运行中,动态的向某个对象提供它所需要的其他对象。 (4). 依赖注入的思想是通过反射机制实现的,在实例化一个类时,它通过反射调用类中set方法将事先保存在HashMap中的类属性注入到类中。 总而言之,在传统的对象创建方式中,通常由调用者来创建被调用者的实例,而在Spring中创建被调用者的工作由Spring来完成,然后注入调用者,即所谓的依赖注入or控制反转。 注入方式有两种:依赖注入和设置注入; IoC的优点:降低了组件之间的耦合,降低了业务对象之间替换的复杂性,使之能够灵活的管理对象。 AOP(Aspect Oriented Programming) (1). AOP面向方面编程基于IoC,是对OOP的有益补充; (2). AOP利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了 多个类的公共行为封装到一个可重用模块,并将其名为"Aspect",即方面。所谓"方面",简单地说,就是将那些与业务无关,却为业务模块所共同调用的 逻辑或责任封装起来,比如日志记录,便于减少系统的重复代码,降蚂蚁云客服机器人面试答案全文共6页,当前为第3页。蚂蚁云客服机器人面试答案全文共6页,当前为第3页。低模块间的耦合度,并有利于未来的可操作性和可维护性。 蚂蚁云客服机器人面试答案全文共6页,当前为第3页。 蚂蚁云客服机器人面试答案全文共6页,当前为第3页。 (3). AOP代表的是一个横向的关 系,将"对象"比作一个空心的圆柱体,其中封装的是对象属性和行为;则面向方面编程的方法,就是将这个圆柱体以切面形式剖开,选择性的提供业务逻辑。而 剖开的切面,也就是所谓的"方面"了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹,但完成了效果。 (4). 实现AOP的技术,主要分为两大类:一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;二是采用静态织入的方式,引入特定的语法创建"方面",从而使得编译器可以在编译期间织入有关"方面"的代码。 (5). Spring实现AOP:JDK动态代理和CGLIB代理 JDK动态代理:其代理对象必须是某个接口的实现,它是通过在运行期间创建一个接口的实现类来完成对目标对象的代理;其核心的两个类是InvocationHand

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值