最初的Java EE(现被Oracle公司改称Jakarta EE,真会玩😂)规范由Sun公司制定,包含JDBC、JNDI、JavaBean、Annotation、JPA、CDI(容器依赖注入)等多项重量级技术,其实现纷繁复杂。
而Spring框架轻量实现Java EE技术,封装诸如JDBC、JavaMail多项技术降低使用难度,且实现控制反转(IoC)模式与面向切面编程(AOP)的独特功能大大解放程序员双手!
IoC
IoC(控制反转,即对象控制权转交至容器)是一种全新的设计模式,通过DI(依赖注入,即自动注入被依赖属性)将对象的创建与维护转交IoC容器(或称工厂)控制。用户仅需编写(xml)配置文件无需 new
操作即可降低代码耦合度。
其原理类似工厂模式的反射机制 Class.forName(str).newInstance()
。
AOP
AOP(面向切面编程)是一种函数式编程的技术。通过预编译或动态代理插入执行业务无关片段,如日志记录、安全控制、性能统计。用户无需增添业务内容从而降低代码耦合度。
通俗地说,视业务代码为面团,视插入代码段为可多次重复切入使用的刀片,刀切面行为就是面向切面编程。如下图所示
- 预编译指在编译过程中插入代码段,需要相关编译器,实现代表有AspectJ框架。
-
动态代理指在执行过程中动态生成代理对象,无需特定编译器,实现代表分为JDK及CGLIB类库:
-
JDK采用反射机制实现动态代理,仅代理接口,使用方式如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43public interface {
void doJob();
}
public class ExampleImpl implements {
public void doJob() {
System.out.println("Running method: doJob()");
}
}
public class ProxyHandler implements InvocationHandler {
private Object target;
public ExampleHandler(Object target) {
this.target = target;
}
public Object invoke(Object proxyObject, Method method, Object[] args) throws Throwable {
System.out.println("Before method: " + method.getName());
Obeject result = method.invoke(target, args);
System.out.println("After method: " + method.getName());
return result;
}
}
public class ProxyUtil {
//该方法无需改动
"unchecked") (
public static <T> T getProxy(Object target) {
ProxyHandler proxyHandler = new ProxyHandler(target);
//第一个参数用于生成代理类,第二个参数用于指定代理接口集合,第三个参数用于实现代理对象方法
T proxy = (T) Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
proxyHandler
);
return proxy;
}
}
public class Test {
public static void main(String[] args) {
Example example = Proxy.getProxy(new ExampleImpl());
example.doJob();
}
}newProxyInstance
方法实现原理如下:`
Java
public static Object newProxyInstance(ClassLoader classLoader, Class<?>[] intfs, InvocationHandler handler) throws IllegalArgumentException {
Objects.requireNonNull(handler);
final Class<?>[] interfaces = intfs.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null)checkProxyAccess(Reflection.getCallerClass(), classLoader, interfaces);
//创建代理类
Class<?> clazz = getProxyClass0(classLoader, interfaces);
/*- 根据生成的class通过反射获取构造函数对象并生成代理类实例
*/
try {
if (sm != null) {checkNewProxyPermission(Reflection.getCallerClass(), clazz);
}
final Constructor<?> constructor = clazz.getConstructor(constructorParams);
final InvocationHandler finalHandler = handler;
if (!Modifier.isPublic(cl.getModifiers())) {AccessController.doPrivileged(new PrivilegedAction<Void>() { public Void run() { cons.setAccessible(true); return null; } });
}
return cons.newInstance(new Object[]{h});
} catch (IllegalAccessException|InstantiationException e) {
throw new InternalError(e.toString(), e);
} catch (InvocationTargetException e) {
Throwable t = e.getCause();
if (t instanceof RuntimeException) {throw (RuntimeException) t;
} else {
throw new InternalError(t.toString(), t);
}
} catch (NoSuchMethodException e) {
throw new InternalError(e.toString(), e);
}
}Struts简史
- 根据生成的class通过反射获取构造函数对象并生成代理类实例
-
过滤器(filter)
Struts2原理
Struts2使用
环境配置
创建action
本文采用 CC BY-NC-SA 3.0 Unported 协议进行许可
近期评论