A.代理模式
(一)定义
通过代理对象来访问目标对象就叫做代理模式,其意是在不修改原代码的情况下拓展功能。
(二)应用场景
在已有的代码上扩展功能,在原代码上添加代码会造成以下不便:
1、职责不够单一;
2、代码复用性不好;
3、不方便后期维护
此时,考虑使用代理模式。
应用场景:添加日志记录、性能统计、事务管理等。
(三)分类
一、jdk静态代理
1、核心作用
通过代理对象控制对目标对象的访问,可以在调用目标方法前或目标方法之后做一些功能增强;
2、实现要求和步骤
(1)必须要有一个接口;
(2)代理类和委托类实现同一个接口;
(3)在代理类内部维护一个委托类的引用对象;
(4)在代理类中执行目标方法,并在其前后增强功能。
3、缺点
(1)必须要有接口,且委托类和代理类需实现同一个接口,会产生很多类,不便于管理;
(2)如果接口中增加方法,则委托类和代理类都要做相应的维护,不灵活。
二、jdk动态代理
1、作用
2、缺点
3、实现要求和步骤
(1)委托类必须要有接口;
(2)代理工厂选择性实现InvocationHandler接口;
不需要和委托类实现同一个接口;
(3)在代理工厂内部维护一个Object类型的引用target(只声明,不赋值);
(4)以target为参数创建构造函数;
(5)通过Java.lang.reflect.Proxy这个类创建代理对象:
通过类名Proxy调用其静态方法:
newProxyInstance(
目标类的加载器,
目标类实现的接口的类型,
InvocationHandler的实例)
此处获得invocationHandler的实例的两种方法:
1)代理工厂实现invocationHandler方法,重写其invoke方法,在设置实例的地方传入this;
invoke方法中三个参数:当前代理类的对象proxy,目标类要执行的方法method,目标方法的参数args。在invoke方法中通过反射执行目标方法,并在执行目标方法前后执行增强的功能。
2)在invocationHandler实例的地方创建一个invocationHandler的匿名内部类,在匿名内部类中,重写其invoke方法,invoke方法中三个参数:当前代理类的对象proxy,目标类要执行的方法method,目标方法的参数args。在invoke方法中通过反射执行目标方法,并在执行目标方法前后执行增强的功能。
注意:InvocationHandler的实例是执行目标对象的方法时,会触发事件处理器的方法,会把当前执行目标对象的方法作为参数传入。
(6)返回代理对象。
4、代码示例
public class DynamicFactory {
//1、在代理工厂内维护一个object类的引用,targrt是目标对象
private Object target;
//2、创建有参构造函数
public DynamicFactory(Object target) {
super();
this.target = target;
}
//3、创建方法获取代理对象
public Object getInstance(Object target) {
Object proxy = Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//执行目标方法
Object result = method.invoke(target, args);
//后置日志
System.out.println(new Date().toString());
return result;
}
});
return proxy;
}
}
三、cglib动态代理
1、实现代理原理
(1)通过继承目标类,通过目标类的子类来完成功能增强。
(2)Enhancer允许为非接口类型动态创建一个代理对象,该代理对象对给定类型的子类,拦截了所有方法。
注意:
1)目标对象不能被final修饰;
2)实现cglib动态代理需要导入jar包:cglib和asm。
2、优点
3、实现要求和步骤
(1)导入jar包:cglib、asm;
(2)委托类有接口和没有接口都可以;
(3)创建代理工厂,选择性实现一个接口:MethodInterceptor;
(4)在代理工厂内部维护一个Object类型的引用(只声明,不赋值);
(5)以target作为参数构建一个有参构造函数;
(6)通过Enhancer对象创建代理对象:
1)设置一个父类作为模板,用这个父类,动态生成一个子类;
2)设置一个回调对象:MethodInterceptor的实例,在MethodInterceptor接口中所定义的interceptor方法中去执行目标的方法以及增强的功能。
此处创建MehotdInterceptor实例的两种方式:
①代理工厂实现MenthodInterceptor接口,重写interceptor方法,在设置实例的地方,传this;
interceptor第一个参数为当前代理对象,第二个参数为当前要执行的目标方法,第三个参数是当前要执行的目标参数的参数集合;
②在设置实例的地方,创建一个MethodInterceptor的匿名内部类,在匿名内部类中重写interceptor方法,在方法中执行目标方法和增强。
interceptor第一个参数为当前代理对象,第二个参数为当前要执行的目标方法,第三个参数是当前要执行的目标参数的参数集合;
(7)返回代理对象
4、代码示例
public class CglibFactory {
//1、维护Object的引用
private Object target;
//2、创造有参构造器
public CglibFactory(Object target) {
super();
this.target = target;
}
//3、创建代理对象
public Object getProxyInstance(){
//创建enhancer对象
Enhancer enhancer = new Enhancer();
//将目标类设为enhancer的父类
enhancer.setSuperclass(target.getClass());
//设置回调对象
enhancer.setCallback(new MethodInterceptor() {
@Override
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy arg3) throws Throwable {
Object result = method.invoke(target, args);
System.out.println(new Date().toString());
return result;
}
});
return enhancer.create();
}
}
B.spring入门基础理论
一、什么是spring
1、spring是一个分层的JavaSE/EE 一站式(full-stack)轻量级开源框架;
2、轻量级:依赖资源少,销毁的资源少,需要什么资源就加载什么资源;
3、分层:特点:一站式,每一层都提供相应的解决方法
web层 | service层 | dao层 |
---|---|---|
struts、springMVC | spring | jdbcTemplate、mybatis、hibernate |
二、spring的由来
Spring 是java平台上的一个开源应用框架。它的第一个版本是由Rod Johnson写出来的。
三、spring的核心
spring的核心是控制反转(IOC)和面向切面编程(AOP);
四、spring的优点
1、方便解耦
spring是一个大型工厂,用于创建所有的对象,以及维护相互的依赖关系。
2、AOP编程的支持
面向切面编程:可以方便的实现对程序进行权限拦截、运行监控等功能;
3、声明时事务的支持
4、方便程序的测试
5、方便集成各种优秀的框架
spring内部提供了对各种优秀框架的直接支持:Hibenate、Mybatis、Quartz等;
6、降低JavaEE的API的使用难度
spring对JavaEE中比较难用的API进行了封装,使用难度大大降低。
五、spring的结构体系
1、五个核心模块
核心容器core | spring-core:控制反转IOC和依赖注入DI的最基本实现 |
---|---|
spring-beans:bean工厂,以及bean的装配 | |
spring-context:spring的context上下文,及IOC容器 | |
spring-expression:spring的表达式语言 | |
面向切面编程AOP | spring-aop:面向切面编程 |
spring-aspects:集成AspectJ | |
spring-instrument:提供一些类级的工具支持和ClassLoader级的实现,用于服务器; | |
spring-instrument-tomcat:针对tomcat的instrument的实现; | |
数据访问 | spring-jdbc:jdbc的支持 |
spring-tx:事务控制 | |
spring-orm:对象关系映射,集成orm框架 | |
spring-oxm:对象xml的映射 | |
spring-jms:Java消息服务 | |
web | spring-web:基础的web功能,如文件上传 |
spring-webmvc:mvc实现 | |
spring-webmvc-portlet:基于portlet的mvc实现 | |
spring-websocket:为web应用提供的高效通信工具 | |
test | spring-test:spring测试,提供junit与mock测试功能 |
spring-context-support:spring额外支持包 | |
spring4新增 | spring-websocket:为web应用提供高效的通信工具 |
``` |
spring-messaging:用于构建基于消息的应用程序 ``` |
2、相互依赖关系
(1)核心容器core相互依赖关系
(2)aop模块相互依赖关系
(3)数据库访问模块的相互依赖关系
(4)web模块相互依赖关系
(5)test模块相互依赖关系
(6)spring4新增模块依赖关系
六、spring用到的技术
七、搭建spring框架开发环境
1、基本spring框架需要的jar包
(1)日志包:commons-logging;
(2)核心包4个:core、beans、context、expression
(3)aop
2、xml方式配置spring
步骤
(1)导入jar包
(2)创建spring的xml配置文件
文件名称:applicationContext.xml;
文件位置:类路径下(classpath);
(3)配置spring的xml配置文件
1)引入约束:beans;
2)在xml配置文件中声明定义好的bean;有属性或者其他依赖,在bean结点下添加property结点;
注意:
①在一个类维护另一个类的引用时,使用其接口;在bean结点中的id名使用其接口名首字母小写;
②在一个类中维护另一个类的引用时,还需保证被引用的对象在本类中有set和get方法。
(4)测试
1)加载new ClassPathXmlApplicationContext(“xml配置文件路径”);
2)获取spring的上下文对象:applicationContext对象;
3)通过applicationContext对象调用方法getBean()获取注册的bean。