Spring框架静态代理和动态代理

1、域属性注入

  创建实体类Student

package com.spring.entity;

public class Student {
    //普通属性
    private  Integer id;
    private String name;

    //域属性
    private Car car;

    public Car getCar() {
        return car;
    }

    public void setCar(Car car) {
        this.car = car;
    }
public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

  创建实体类Car类

package com.spring.entity;

public class Car {
    private String type;//汽车的类型
    private  String color;//汽车的颜色

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }
}

  (1)byType

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
 <!--使用域属性注入,byType方式-->
    <bean id="car" class="com.spring.entity.Car">
        <property name="color" value="蓝色"></property>
        <property name="type" value="奥迪"></property>
    </bean>

    <!--在Student中装配     autowire:所对应的方式-->
    <bean id="student" class="com.spring.entity.Student" autowire="byType">
        <property name="name" value="张三"></property>
        <property name="id" value="1"></property>
    </bean>
</beans>

  运行结果如下

  

  (2)byName

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
 <!--byName方式:要求Car类的id和Student类中的域属性Car对象的对象名一致-->
    <bean id="car" class="com.spring.entity.Car">
        <property name="color" value="红色"></property>
        <property name="type" value="奔驰"></property>
    </bean>

    <bean id="student" class="com.spring.entity.Student" autowire="byName">
        <property name="name" value="李四"></property>
        <property name="id" value="2"></property>
    </bean>
</beans>

  运行结果如下

  

2、数组属性

  定义实体类DITest  

package com.spring.entity;

import java.util.*;

public class DITest {
    //定义String类型数组
    private String[] arrays;

    //定义一个List集合
    private List<Integer> lists;

    //定义一个Set集合
    private Set<String> sets;

    //定义一个Map集合
    private Map<String,Object> maps;

    //配置
    private Properties properties;

    @Override
    public String toString() {
        return "DITest{" +
                "arrays=" + Arrays.toString(arrays) +
                ", lists=" + lists +
                ", sets=" + sets +
                ", maps=" + maps +
                ", properties=" + properties +
                ‘}‘;
    }

    public String[] getArrays() {
        return arrays;
    }

    public void setArrays(String[] arrays) {
        this.arrays = arrays;
    }

    public List<Integer> getLists() {
        return lists;
    }

    public void setLists(List<Integer> lists) {
        this.lists = lists;
    }

    public Set<String> getSets() {
        return sets;
    }

    public void setSets(Set<String> sets) {
        this.sets = sets;
    }

    public Map<String, Object> getMaps() {
        return maps;
    }

    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }
}

  定义相对应的applicationContextDITest.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:p="http://www.springframework.org/schema/p"

       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd

       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd">
    <bean id="dITest" class="com.spring.entity.DITest">
        <!--数组属性-->
        <property name="arrays">

            <!--String集合-->
            <array>
                <value>王楠</value>
                <value>郑楠</value>
                <value>史志慧</value>
            </array>
        </property>

        <!--list数组-->
        <property name="lists">
            <list>
                <value>16</value>
                <value>19</value>
                <value>18</value>
            </list>
        </property>

        <!--set数组-->
        <property name="sets">
            <set>
                <value>吃饭</value>
                <value>睡觉</value>
                <value>打豆豆</value>
            </set>
        </property>

        <!--map集合-->
        <property name="maps">
            <map>
                <entry key="name" value="陈晨"></entry>
                <entry key="age" value="18"></entry>
            </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>
</beans>

  Test测试类对应如下

package com.spring.test;

import com.spring.entity.DITest;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Idtest {
    @Test
    public void say(){
        ApplicationContext cxt=new ClassPathXmlApplicationContext("applicationContextDITest.xml");
        DITest dITest = (DITest) cxt.getBean("dITest");
        System.out.println(dITest.toString());
    }
}

  运行结果如下

    

3、静态代理

  (1)什么是静态代理:

    说白了,就是创建一个给程序调用的类(代理类),然后用代理类去吊原始对象 (2)对应的案例    创建抽象类Subject并定义其方法
package com.spring.Subject;

/**
 * 抽象类:真实业务接口
 */
public interface Subject {
    public void doSome();
}

    创建Subject实现类RealSubject

package com.spring.Subject.impl;

import com.spring.Subject.Subject;
/**
 * 真实主题:将业务代码封装到此主题中
 */
public class RealSubject implements Subject {
    @Override
    public void doSome() {
        System.out.println("=============真实业务============");
    }
}

    创建中间类ProxySubject

package com.spring.ProxySubject;

import com.spring.Subject.Subject;
import com.spring.Subject.impl.RealSubject;

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

    Test测试类

package com.spring.ProxyTest;

import com.spring.ProxySubject.ProxySubject;

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

    运行结果如下

      

4、JDK动态代理

package com.spring.JDK;

import com.spring.Subject.Subject;
import com.spring.Subject.impl.RealSubject;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class JDKTest {
    public static void main(String[] args) {
        //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);
    }
}

  运行结果如下

    

5、CGLIB动态代理

  (1)创建IService类

package com.spring.CGLIB;

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

  (2)创建CGLIBTest类

package com.spring.CGLIB;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

public class CGLIBTest {
    public static void main(String[] args) {
        //步骤一:目标对象
        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();
    }
}

  运行结果如下

    

原文地址:https://www.cnblogs.com/tinghao/p/11752922.html

时间: 2024-07-29 17:45:32

Spring框架静态代理和动态代理的相关文章

Spring框架5:事务和动态代理

事务 我们在service中加一个转账的功能 public void transfer(String sourceName, String targetName, Float money) { Account source = accountDao.findAccountByName(sourceName); Account target = accountDao.findAccountByName(targetName); source.setMoney(source.getMoney() -

Spring静态代理与动态代理

代理模式 1.什么是代理模式? 真实生活中有一种房屋中介是这样的,租客根本就不知道房东是谁,一切签合同.交租金.交钥匙等操作都直接和中介公司发生.我们把这种模式称之为代理模式. 代理模式:客户端直接使用的都是代理对象,不知道目标对象是谁,此时代理对象可以在客户端和目标对象之间起到中介的作用. 2.特点 代理对象完全包含目标对象,客户端使用的都是代理对象的方法,和目标对象没有直接关系 3.职责 把不是目标对象该做的事情从目标对象上撇开——职责清晰. 4.分类 静态代理:在程序运行前就已经存在代理类

spring静态代理和动态代理

本节要点: Java静态代理 Jdk动态代理 1 面向对象设计思想遇到的问题 在传统OOP编程里以对象为核心,并通过对象之间的协作来形成一个完整的软件功能,由于对象可以继承,因此我们可以把具有相同功能或相同特征的属性抽象到一个层次分明的类结构体系中.随着软件规范的不断扩大,专业化分工越来越系列,以及OOP应用实践的不断增多,随之也暴露了一些OOP无法很好解决的问题. 现在假设系统中有三段完全相似的代码,这些代码通常会采用"复制"."粘贴"方式来完成,通过这种方式开发

【设计模式】代理模式:静态代理,动态代理,spring aop

代理模式分为静态代理和动态代理.我们拿链家来举例子,我们本人是真实的对象,有真实的业务需求:需要去找房子:链家是中介,是代理类,他来帮我执行找房子的这个操作. 静态代理: 1.实现一个接口 public interface SearchHome { public void search(); } 2.构建实现接口的委托类 public class Master implements SearchHome { @Override public void search() { System.out.

Atitit 代理CGLIB&#160;动态代理&#160;AspectJ静态代理区别

Atitit 代理CGLIB 动态代理 AspectJ静态代理区别 1.1. AOP 代理主要分为静态代理和动态代理两大类,静态代理以 AspectJ 为代表:而动态代理则以 spring AOP 为代表 1 1.2. JDK动态代理是模拟接口实现的方式,cglib是模拟子类继承的方式1 1.3. CGLIB代理模式的缺点 在static和final方法上应用横切关注点也是无法做到的.2 1.1. AOP 代理主要分为静态代理和动态代理两大类,静态代理以 AspectJ 为代表:而动态代理则以 

Java代理之(jdk静态代理/jdk动态代理/cglib动态代理/aop/aspectj)

一.概念 代理是什么呢?举个例子,一个公司是卖摄像头的,但公司不直接跟用户打交道,而是通过代理商跟用户打交道.如果:公司接口中有一个卖产品的方法,那么公司需要实现这个方法,而代理商也必须实现这个方法.如果公司卖多少钱,代理商也卖多少钱,那么代理商就赚不了钱.所以代理商在调用公司的卖方法后,加上自己的利润然后再把产品卖给客户.而客户部直接跟公司打交道,或者客户根本不知道公司的存在,然而客户最终却买到了产品. 专业点说:代理模式是对象的结构型模式,代码模式给某一个对象提供代理,并由代理对象控制原对象

java 代理模式(静态代理、动态代理、Cglib代理) 转载

Java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩展目标对象的功能.这里使用到编程中的一个思想:不要随意去修改别人已经写好的代码或者方法,如果需改修改,可以通过代理的方式来扩展该方法 代理模式最大的特点就是代理类和实际业务类实现同一个接口(或继承同一父类),代理对象持有一个实际对象的引用,外部调用时操作的是代理对象,而在代理对象的内部实现中又会去调

java中静态代理和动态代理

一.概述 代理是一种模式,提供了对目标对象的间接访问方式,即通过代理访问目标对象.如此便于在目标实现的基础上增加额外的功能操作,前拦截,后拦截等,以满足自身的业务需求,同时代理模式便于扩展目标对象功能的特点也为多人所用. 按照代理的创建时期,代理类可以分为两种: 静态:由程序员创建代理类或特定工具自动生成源代码再对其编译.在程序运行前代理类的.class文件就已经存在了. 动态:在程序运行时运用反射机制动态创建而成. 我们根据加载被代理类的时机不同,将代理分为静态代理和动态代理.如果我们在代码编

Spring框架中2种生成代理对象的方法

Spring框架中2种生成代理对象的方法 Jdk Proxy基于接口生成代理对象,只能赋值给接口的引用(默认使用jdk). Spring进一步封装 CGLIB,基于实现类生成代理对象,既可以赋值给接口的引用,也可以赋值给实现类的引用 JDK提供的Proxy,和spring进一步封装的CGLIB.二者生成的代理没有任何区别,生成的都是代理对象.只是生产方式不同,前者是基于接口生成代理,后者基于实现类生成代理对象 如何切换spring框架中默认生成代理的方式 <aop:config proxy-ta

Spring之AOP原理_动态代理

面向方面编程(Aspect Oriented Programming,简称AOP)是一种声明式编程(Declarative Programming).声明式编程是和命令式编程(Imperative Programming)相对的概念.我们平时使用的编程语言,比如C++.Java.Ruby.Python等,都属命令式编程.命令式编程的意思是,程序员需要一步步写清楚程序需要如何做什么(How to do What).声明式编程的意思是,程序员不需要一步步告诉程序如何做,只需要告诉程序在哪些地方做什么