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();
    }
}

输出

 

posted @ 2019-10-28 15:22  听风忆雪  阅读(150)  评论(0编辑  收藏  举报