Spring之面向接口增强实现类

2 篇文章 0 订阅

Spring之面向接口增强实现类

使用场景:在不修改原有代码的 或者没有办法修改原有代码的情况下 增强对象功能 使用代理对象 代替原来的对象去完成功能进而达到拓展功能的目的
代理模式
是通过代理对象访问目标对象,这样可以在目标对象基础上增强额外的功能,如添加权限,访问控制和审计等功能。
例如:房产中介代替业主卖房

静态代理
静态代理中代理类与被代理类都需要实现同一个接口,这就说明我们的一个静态代理类只能代理一个类,并且还要事先知道我们要代理哪个类才能写代理类,如果我们有其他类还想使用代理那就必须再写一个代理类。
然而在实际开发中我们是可能是有非常多的类是需要被代理的,并且事先我们可能并不知道我们要代理哪个类。所以如果继续使用静态代理反而会增加许多的工作量,并且效率低下,代码复用率也不好。

package com.mrshun.test;

public class Test1 {

    public static void main(String[] args) {
        Person person=new Person("张三");
        Lawyer lawyer=new Lawyer(person);
        lawyer.doCourt();
    }
}

interface Court{
    void doCourt();
}

class Lawyer implements Court{
    private Person person;

    public Lawyer(Person person) {
        this.person=person;
    }

    @Override
    public void doCourt() {
        System.out.println("律师取证:视频证明张三当时不在案发现场");
        person.doCourt();
    }
}

class Person implements Court{

    private String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public void doCourt() {
        System.out.println(name+"说:我没有杀人");
    }
}

动态代理
动态代理可以针对于一些不特定的类或者一些不特定的方法进行代理,我们可以在程序运行时动态的变化代理的规则,代理类在程序运行时才创建的代理模式成为动态代理。这种情况下,代理类并不是在Java代码中定义好的,而是在程序运行时根据我们的在Java代码中的“指示”动态生成的

  1. Proxy 动态代理 JDK动态代理 面向接口

  2. cglib 动态代理 第三方动态代理 面向父类

 package com.mrshun.testProxy;

import javax.swing.*;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

public class Test1 {
    public static void main(String[] args) {
        final Dinner dinner=new Person("张三");
        //通过Proxy动态代理获得一个代理对象,在代理对象中,对某个方法进行增强
        //ClassLoader loader, 被代理的类加载器
        ClassLoader classLoader = dinner.getClass().getClassLoader();
        //Class<?>... interfaces,被代理对象所实现的所有接口
        Class[] interaces= dinner.getClass().getInterfaces();
        //InvocationHandler h,执行处理对象,专门用于定义增强的规则
        InvocationHandler handler=new InvocationHandler(){
            //invoke 当我们让代理对象调用任何方法时,都会触发invoke方法
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                Object res;
                //object proxy,被代理对象
                //System.out.println(proxy);//proxy-->invoke-->proxy
                //Method method,被代理的方法
                System.out.println(method.getName());
                //object[] args,被代理对象方法运行的实参
                if(method.getName().equals("eat")){
                    System.out.println("饭前洗手");
                    res = method.invoke(dinner,args);
                    System.out.println("饭后刷碗");
                }else {
                    res = method.invoke(dinner,args);
                }
                System.out.println(Arrays.toString(args));
                return null;
            }
        };
        Dinner dinnerProxy=(Dinner) Proxy.newProxyInstance(classLoader,interaces,handler);
        //dinnerProxy.eat("包子");
        dinnerProxy.drink();
    }
}

interface Dinner{
    void eat(String  footName);
    void drink();
}

class Person implements Dinner{
    private String name;

    public Person(String name) {
        this.name = name;
    }

    @Override
    public void eat(String footName) {
        System.out.println(name+"正在吃"+footName);
    }


    @Override
    public void drink() {
        System.out.println(name+"正在喝茶");
    }
}

class Student implements Dinner{
    private String name;

    public Student(String name) {
        this.name = name;
    }

    @Override
    public void eat(String footName) {
        System.out.println(name+"正在吃"+footName);
    }

    @Override
    public void drink() {
        System.out.println(name+"正在喝可乐");
    }
}

使用代理技术 获得代理对象 代替张三 增强打官司的方法

总结

1.在不修改原有代码的 或者没有办法修改原有代码的情况下 增强对象功能 使用代理对象 代替原来的对象去完成功能进而达到拓展功能的目的
2.JDK Proxy 动态代理面向接口的动态代理 一定要有接口和实现类的存在 代理对象增强的是实现类 在实现接口的方法重写的方法生成的代理对象只能转换成 接口的不能转换成 被代理类代理对象只能增强接口中定义的方法 实现类中其他和接口无关的方法是无法增强的代理对象只能读取到接口中方法上的注解 不能读取到实现类方法上的注解

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
spring-core.jar(必须):这个jar 文件包含Spring 框架基本的核心工具Spring 其它组件要都要使用到这个包里的,是其它组件的基本核心,当然你也可以在自己的应用系统中使用这些工具。 外部依赖Commons Logging, (Log4J)。 spring-beans.jar(必须):这 个jar 文件是所有应用都要用到的,它包含访问配置文件、创建和管理bean 以及进行Inversion of Control / Dependency Injection(IoC/DI)操作相关的所有。如果应用只需基本的IoC/DI 支持,引入spring-core.jar 及spring-beans.jar 文件就可以了。 外部依赖spring-core,(CGLIB)。 spring-aop.jar(必须):这个jar 文件包含在应用中使用Spring 的AOP 特性时所需的和源码级元数据支持。使用基于AOP 的Spring特性,如声明型事务管理(Declarative Transaction Management),也要在应用里包含这个jar包。 外部依赖spring-core, (spring-beans,AOP Alliance, CGLIB,Commons Attributes)。 spring-context.jar(必须):这个jar 文件在基础IOC功能上为Spring 核心提供了大量扩展服务,此外还提供许多企业级服务的支持,有邮件服务、任务调度、JNDI定位,EJB集成、远程访问、缓存以及多种视图层框架的支持。可以找到使用Spring ApplicationContext特性时所需的全部,JDNI 所需的全部,instrumentation组件以及校验Validation 方面的相关。 外部依赖spring-beans, (spring-aop)。 spring-jdbc.jar(必须) :这个jar 文件包含对Spring 对JDBC 数据访问进行封装的所有。 外部依赖spring-beans,spring-dao。 spring-web.jar(必须) :这个jar 文件包含Web 应用开发时,用到Spring 框架时所需的核心,包括自动载入Web Application Context 特性的、Struts 与JSF 集成、文件上传的支持、Filter 和大量工具辅助。 外部依赖spring-context, Servlet API, (JSP API, JSTL, Commons FileUpload, COS)。 spring-webmvc.jar :这个jar 文件包含Spring MVC 框架相关的所有。包含国际化、标签、Theme、视图展现的FreeMarker、JasperReports、Tiles、Velocity、XSLT相关。包括框架的Servlets,Web MVC框架,控制器和视图支持。当然,如果你的应用使用了独立的MVC 框架,则无需这个JAR 文件里的任何。 外部依赖spring-web, (spring-support,Tiles,iText,POI)。 spring-aspects.jar :提供对AspectJ的支持,以便可以方便的将面向方面的功能集成进IDE中,比如Eclipse AJDT。 spring-context-support.jar:Spring context的扩展支持,用于MVC方面。 spring-expression.jar:Spring表达式语言。 spring-instrument.jar:Spring对服务器的代理接口 spring-instrument-tomcat.jar:Spring对tomcat连接池的集成 spring-jms.jar:为简化jms api的使用而做的简单封装。 外部依赖spring-beans,spring-dao,JMS API。 spring-orm.jar:整合第三方的orm实现,如hibernate,ibatis,jdo以及spring 的jpa实现 spring-oxm.jar:Spring对于object/xml映射的支持,可以让JAVA与XML之间来回切换 spring-messaging.jar: spring-test.jar:对JUNIT等测试框架的简单封装 spring-tx.jar:为JDBC、Hibernate、JDO、JPA等提供的一致的声明式和编程式事务管理。 spring-webmvc-portlet.jar:Spring MVC的增强 spring-websocket.jar:
Spring IOC 控制反转:把创建对象的权利交给Spring 创建对象 1.无参构造<bean class=""> 2.静态工厂<bean class="" factory-method=""> 3.实例工厂 <bean bean-factory="" factory-method=""> 管理对象 对象关系DI 构造器注入<construct-arg> set注入<property> 生命周期 scope:prototype/singleton init-method destroy-method API BeanFactory:使用这个工厂创建对象的方式都是懒加载,在调用的时候再创建 ClassPathXmlApplicationContext:使用这个工厂创建对象,他会根据scope智能判断是否懒加载,如果是单例则创建容器时就会创建里面bean的实例,如果是多例在获取使用时才会创建bean实例 FileSystemXmlApplicationContext磁盘路径 AnnotationConfigApplicationContext注解 WebApplicationContext:web环境使用的容器 注解 创建对象 Component:不分层的注解 Controller:web层 Service:service层 Repository:dao层 管理对象 注入 AutoWired Qualifier Resource Value 声明周期 Scope PostConstruct PreDestroy 新注解 Bean:写方法上,将方法的返回值 Configuration:标记配置 ComponentScan包扫描 PropertySource:加载配置文件 Import:导入其他配置 AOP 概念:面向切面编程,在不改变源码的情况下对方法进行增强,抽取横切关注点(日志处理,事务管理,安全检查,性能测试等等),使用AOP进行增强,使程序员只需要关注与业务逻辑编写. 专业术语 目标Target:需要增强 连接点JoinPoint:目标中可被增强的方法 切入点PointCut:被增强的方法 增强Advice:增强代码 切面Aspect:切点加通知 织入weaving:讲切面加载进内存形成代理对象的过程 代理Proxy 底层实现 JDK动态代理(默认) 基于接口:代理对象与目标对象是兄弟关系,目标必须实现接口 CGLIB动态代理 基于父:代理对象与目标对象是父子关系.目标不能被final修饰 修改默认代理方法:<aop:aspectj-autoproxy proxy-target-class="true"/> 增强 前置通知 后置通知 异常通知 最终通知 环绕通知 注意:使用注解的方式,最终通知和后置通知顺序换了,建议使用环绕通知 注解 配置 声明式事务管理 PlatFormTransactionManager:平台事务管理器:定义了commit/rollback Mybatis/jdbc:DataSourceTransactionManager Hibernater:HibernaterTransactionManager TransactionManagerDifinition 传播行为:A-->B,在B上声明是否一定需要事务管理 requerd:必须的(默认),如果A有事务那么就加入A的事务,如果A没有事务那么单独创建一个事务 supports,如果A有事务则加入,如果没有就算了 隔离级别 default:使用数据库默认的隔离级别(mysql:可重复读,oracle:读已提交) readuncommited:读未提交,不可以解决任何问题 readcommited:读已提交,可以解决脏读问题 repeatableRead:可重复读,可以解决脏读,不可重复读问题 Serializbler:串行化,可以解决所有问题 超时时间: 默认-1(永不超时),事务一直不提交也不回滚的时间 是否只读: 默认false TransactionManagerStatus: 事务的一些状态 整合 Spring整合Junit 1.导入依赖spring-test 2.加注解:RunWith、ContextConfiguration 3.注入对象进行测试 Spring整合web 1.导入依赖spring-web 2.配置ContextLoadListener 3.配置 <!--全局初始化参数--> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> 4.在Servlet中使用WebApplicationContextUtils获取容器对象 5.使用容器对象去获取Service对象

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr顺

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值