• IOC和AOP交互拓展(二)


    注入不同的类型

    public class DiTest {
        /*数组*/
        private String [] arrays;
       /* lIST:有序  且  可重复*/
        private List<Integer> lists;
        /*Set:无序  且  不可重复*/
        private Set<String> sets;
        /*Map*/
        private Map<String,Object> maps;
        /*配置*/
        private Properties properties;
    
        public String[] getArrays() {
            return arrays;
        }
    
        public void setArrays(String[] arrays) {
            this.arrays = arrays;
        }

    配置

    <bean id="diTest" class="com.spring.entity.DiTest">
            <!--数组属性-->
            <property name="arrays">
                <!--数组-->
                <array>
                    <value>张三</value>
                    <value>李四</value>
                </array>
            </property>
            <!--list-->
            <property name="lists">
                <list>
                    <value>18</value>
                    <value>19</value>
                </list>
            </property>
            <!--set-->
            <property name="sets">
                <set>
                    <value>宇宙无敌美少女祝愿是也</value>
                    <value>快下课了,他想变身</value>
                </set>
            </property>
            <!--Map-->
            <property name="maps">
                <map>
                    <entry key="name" value="王洪涛"/>
                    <entry key="age" value="18"/>
                </map>
            </property>
            <!--properties-->
            <property name="properties">
                <props>
                    <prop key="jdbc.driver">com.mysql.jdbc.Driver</prop>
                    <prop key="jdbc.username">root</prop>
                </props>
            </property>
        </bean>

    测试

     public void diTest(){
            //步骤一:加载配置文件
            ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
            DiTest diTest=(DiTest)ctx.getBean("diTest");
            System.out.println(diTest.toString());

    输出

     域属性自动注入byName和byType

    public class Student {
        //普通属性
        private Integer stu_id;
        private String stu_name;
    
        public Student() {
            System.out.println("Bean开始初始化");
        }
    
        //域属性
        private Teacher teacher;
    
        public Teacher getTeacher() {
            return teacher;
        }
    
        public void setTeacher(Teacher teacher) {
            this.teacher = teacher;
        }
    
        public Integer getStu_id() {
            return stu_id;
        }
    
        public void setStu_id(Integer stu_id) {
            this.stu_id = stu_id;
        }
    public class Teacher {
        private Integer t_id;
        private String t_name;
    
        public Integer getT_id() {
            return t_id;
        }
    
        public void setT_id(Integer t_id) {
            this.t_id = t_id;
        }
    
        public String getT_name() {
            return t_name;
        }
    
        public void setT_name(String t_name) {
            this.t_name = t_name;
        }
    }

    配置

    <!--byName约束:bean当中的域属性名必须跟所注入bean的id相同-->
        <!--<bean id="student" class="cn.spring.entity.Student" autowire="byName">
            <property name="stu_id" value="1"></property>
            <property name="stu_name" value="张三"></property>
            &lt;!&ndash;域属性注入   手动 通过  ref指向所引用的bean&ndash;&gt;
            &lt;!&ndash;<property name="teacher" ref="teacher"></property>&ndash;&gt;
        </bean>-->
    
    
        <!--byType:要求被注入域属性类型只能唯一,与其向兼容的类型也同样不可以-->
        <bean id="student" class="com.spring.entity.Student" autowire="byType" scope="prototype">
            <property name="stu_id" value="1"></property>
            <property name="stu_name" value="张三"></property>
           <!-- &lt;!&ndash;域属性注入   手动 通过  ref指向所引用的bean&ndash;&gt;
            &lt;!&ndash;<property name="teacher" ref="teacher"></property>&ndash;&gt;-->
        </bean>
    
        <bean id="teacher" class="com.spring.entity.Teacher">
            <property name="t_id" value="1"></property>
            <property name="t_name" value="王洪涛"></property>
        </bean>

    代理

    接口

    /**
     * 抽象主题:真实业务接口
     */
    public interface Subject {
        public void doSome();
    }
    /**
     * 真实主题:将业务代码封装到此主题当中
     */
    public class RealSubject implements Subject{
        @Override
        public void doSome() {
            System.out.println("==================真实业务=====================");
        }
    }
    /**
     * 代理主题:代理类     生成真实主题对象,调用真实主题的方法
     * 程序就不用直接去创建真实主题了,直接调用代理对象
     *
     * 静态代理:说白了,就是创建一个给程序调用的类(代理类),然后用代理类去吊原始对象
     */
    public class ProxySubject implements Subject{
        //真实主题
        private Subject subject=new RealSubject();
        @Override
        public void doSome() {
            //AOP思想:增强
            System.out.println("前置增强==================");
            subject.doSome();
            System.out.println("后置增强==================");
        }
    }

    测试类

    public class ProxyTest {
        public static void main(String[] args) {
            //程序调用代理对象
            ProxySubject proxySubject=new ProxySubject();
            proxySubject.doSome();
        }
    }

    输出

    JDK动态代理

    接口

    /**
     * 抽象主题:真实业务接口
     */
    public interface Subject {
        public void doSome();
    }
    /**
     * 真实主题:将业务代码封装到此主题当中
     */
    public class RealSubject implements Subject {
        @Override
        public void doSome() {
            System.out.println("==================真实业务=====================");
        }
    }
    public class JDKProxyTest {
        public static void main(String[] args) {
            //JDK动态代理,利用了Proxy类生成代理对象      运行期间    必须原对象必须拥有interface   在内存当中生成代理对象
            //cglib动态代理:在编译期间,利用Enhancer类生成代理对象(要求原对象可以不具备接口)
            
    
            //JDK动态代理:要求必须有抽象主题
            //代表的是代理对象  指定对象的原始类型
    
            /**
             * ClassLoader loader,   类加载器:应该是代理对象的类加载器
             * Class<?>[] interfaces,   接口:原始对象实现的接口类型
             * InvocationHandler h
             */
            //创建一个原始对象
            final Subject subject=new RealSubject();
            Subject subjectProxy = (Subject) Proxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), new InvocationHandler() {
                /**
                 *
                 * @param proxy   代理对象
                 * @param method    目标代理方法
                 * @param args      目标代理方法的参数
                 * @return
                 * @throws Throwable
                 */
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("前置增强");
                    //如何去调用原始对象的业务方法
                    Object invoke = method.invoke(subject, args);
                    System.out.println("后置增强");
                    return invoke;
                }
            });
            subjectProxy.doSome();
            System.out.println(subject);
            System.out.println(subjectProxy);

    测试类

    public class JdkTest {
        public static void main(String[] args) {
    
        final Subject subject=new RealSubject();
        Subject subjectProxy= (Subject) Proxy.newProxyInstance(subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("前置增强");
                Object invoke = method.invoke(subject, args);
                System.out.println("后置增强");
                return invoke;
            }
        });
        subjectProxy.doSome();
            System.out.println(subject);
            System.out.println(subjectProxy);
        }
    }

    输出

    CGLIB动态代理

    /**
     * 业务类
     */
    public class IService {
        public void doSome(){
            System.out.println("我是实现业务的方法");
        }
    }

    测试类

    public class CglibProxyTest {
        public static void main(String[] args) {
            //CGLIB动态代理(当前项目必须有CGLIB的支持)
    
            //步骤一:目标对象
            final IService iService=new IService();
            //步骤二:通过CGLIB提供的Enhancer类生成代理
            Enhancer enhancer=new Enhancer();
            //步骤三:指定需要代理的目标对象模板(将目标对象放入到代理工厂当中,生成代理对象)
            enhancer.setSuperclass(iService.getClass());
            //步骤四:实现增强的处理操作
            enhancer.setCallback(new MethodInterceptor() {
                /**
                 *
                 * @param o             目标对象
                 * @param method        目标对象的方法
                 * @param objects       目标对象方法内的参数
                 * @param methodProxy   代理目标对象方法
                 * @return
                 * @throws Throwable
                 */
                @Override
                public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                    System.out.println("前置");
    
                    Object invoke = methodProxy.invoke(iService, objects);
                    System.out.println("后置");
                    return invoke;
                }
            });
            //最后一步:创建代理
            IService iServiceProxy = (IService)enhancer.create();
            iServiceProxy.doSome();
        }
    }

    输出

  • 相关阅读:
    grafana里prometheus查询语法
    Linux 高频工具快速教程
    国内开源镜像站点汇总
    Oracle DBLINK 简单使用
    启动OpenOffice服务
    使用openoffice转pdf,详细
    ORACLE数据库误操作执行了DELETE,该如何恢复数据?
    一个 介绍 superset Kylin 以及大数据生态圈的 博文
    Kylin介绍 (很有用)
    找到一些经验,关于使用thymeleaf时遇到的一些问题
  • 原文地址:https://www.cnblogs.com/Chencheno/p/11752543.html
Copyright © 2020-2023  润新知