目标:
学习跟随着书:“Java EE互联网轻量型级框架整合开发,代码也来自这本书。”
1、学习反射技术,掌握反射的基本概念
Java反射技术应用广泛,它能够配置:类的全限定名(绝对路径)、方法和参数,完成对象的初始化,甚至是反射某些方法。这样就能可以大大增强Java的可配置性。
Java的反射内容繁多,包括对象构建、反射方法、注解、参数、接口等。在Java中,反射是通过包java.lang.reflect.*来实现的。
通过反射构建对象
public class ReflectServiceImpl {
public void sayHello(String name) {
System.err.println("Hello " + name);
}
}
通过反射的方法去构建它
public ReflectServiceImpl getInstance() {
ReflectServiceImpl object = null;
try {
object =
(ReflectServiceImpl)
Class.forName("com.lean.ssm.chapter2.reflect.ReflectServiceImpl").
getConstructor(String.class).newInstance();
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | NoSuchMethodException
| SecurityException | IllegalArgumentException
| InvocationTargetException ex) {
ex.printStackTrace();
}
return object;
}
下面这行代码的目的就是给类加载器注册了一个类ReflectServiceImple的全限定名,如何通过newInstance方法初始化了一个类对象。
object = (ReflectServiceImpl2) Class.forName(“com.lean.ssm.chapter2.reflect.ReflectServiceImpl2”).newInstance();
2、动态代理和责任链模式,以及拦截器的概念
动态代理的意义在于生成一个占位(代理对象),来代理真实对象,从而控制真实对象的访问。
假设一个场景,你的公司是一家软件公司,你是一位软件工程师。客户带着需求去公司陷入安不会直接和你谈,而是去找商务谈,此时客户会认为商务代表公司。
客户是通过商务去访问软件工程师的,那么商务(代理对象)的意义在于什么?商务可以进行谈判,项目的各个环节,如价格、进度、时间地点。也可能在开发之前谈崩了,此时商务就会按照规则结束与客户的关系,这些东西都不用软件工程师来处理。因此代理的作用就是,在访问工程师(真实对象)前后处理一些对应的逻辑,上面例子中,商务控制着工程师的访问。
经过上面的例子,了解到了代理模式的概念。我们在访问真实对象前,通过代理对象访问真实对象,这个代理对象与真实对象建立代理关系,所以代理分为2个步骤:
1)代理对象和真实对象建立代理关系
2)实现代理对象的代理逻辑方法
JDK代理:
定义接口
public interface HelloWorld {
public void sayHelloWorld();
}
实现接口
public class HelloWorldImpl implements HelloWorld {
@Override
public void sayHelloWorld() {
System.out.println("Hello World");
}
}
这是最坚定的Java接口与实现类的关系,现在可以进行动态代理了。
JDK动态代理中,要实现动态大力逻辑类必须去实现java.lang.reflect.InvocationHandler接口,它里面定义了invoke方法,并提供接口数组用于下挂代理对象
动态代理绑定和代理逻辑实现
public class JdkProxyExample implements InvocationHandler {
// 真实对象
private Object target = null;
/**
* 建立代理对象和真实对象的代理关系,并返回代理对象
*
* @param target真实对象
* @return 代理对象
*/
public Object bind(Object target) {
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
/**
* 代理方法逻辑
*
* @param proxy
* --代理对象
* @param method
* --当前调度方法
* @param args
* --当前方法参数
* @return 代理结果返回
* @throws Throwable
* 异常
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("进入代理逻辑方法");
System.out.println("在调度真实对象之前的服务");
Object obj = method.invoke(target, args);// 相当于调用sayHelloWorld方法
System.out.println("在调度真实对象之后的服务");
return obj;
}
}
测试动态代理
public class ProxyTest {
public static void main(String[] args) {
// testJdkProxy();
tesCGLIBProxy();
}
public static void testJdkProxy() {
JdkProxyExample jdk = new JdkProxyExample();
// 绑定关系,因为挂在接口HelloWorld下,所以声明代理对象HelloWorld proxy
HelloWorld proxy = (HelloWorld) jdk.bind(new HelloWorldImpl());
// 注意,此时HelloWorld对象已经是一个代理对象,它会进入代理的逻辑方法invoke里
proxy.sayHelloWorld();
}
public static void tesCGLIBProxy() {
CglibProxyExample cpe = new CglibProxyExample();
ReflectServiceImpl obj = (ReflectServiceImpl)cpe.getProxy(ReflectServiceImpl.class);
obj.sayHello("张三");
}
}