2.2 IoC组件容器的详细设计:
a. XML文件:记录配置信息。
b. 文件映射类:负责读入XML文件并将文件映射成配置类。(XmlDataLoader)
package com.ehi.pro.util;
public interface XmlDefinitionLoader {
void loadXmlData(String fileName, boolean validating) throws XmlDefinitionException;
}
c. 配置类:与XML文件无关的,记录配置信息类。(BeanDefinitionLoader, BeanInfo, BeanProperty)
BeanDefinitionLoader.java
public interface BeanDefinitionLoader extends XmlDefinitionLoader{
BeanInfo getBeanInfo(String beanName) throws BeanInfoNotFoundException;
}
BeanInfo.java
public interface BeanInfo {
String getClassInfo();
BeanPropertyValue[] getPropertyValues();
boolean isSingleton();
}
d. 加载类:把类对象动态载入。(DynamicClassLoader)
public interface DynamicClassLoader {
public Class loadClass(String className) throws ClassNotFoundException;
}
e. 反射类:获取或者设置类对象的属性。(MethodInvoker)
MethodInvoker.java
public class MethodInvoker {
public static final VoidType VOID = new VoidType();
private static Method validate(Object targetObject, String targetMethod, Object[] arguments) throws ClassNotFoundException, NoSuchMethodException
{
if (targetObject == null) {
throw new IllegalArgumentException("Either targetClass or targetObject is required");
}
if (targetMethod == null) {
throw new IllegalArgumentException("targetMethod is required");
}
if (arguments == null) {
arguments = new Object[0];
}
Class[] types = new Class[arguments.length];
for (int i = 0; i < arguments.length; ++i) {
types[i] = arguments[i].getClass();
}
// try to get the exact method first
Class targetClass = targetObject.getClass();
Method methodObject = null;
try {
methodObject = targetClass.getMethod(targetMethod, types);
}
catch (NoSuchMethodException ex) {
int matches = 0;
Method[] methods = targetClass.getMethods();
for (int i = 0; i < methods.length; ++i) {
Method method = methods[i];
if (method.getName().equals(targetMethod) && method.getParameterTypes().length == types.length) {
methodObject = method;
++matches;
}
}
// just rethrow exception if we can't get a match
if (methodObject == null || matches > 1) {
throw ex;
}
}
return methodObject;
}
public static Object invoke(Object clazz,String methodName,Object[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
Method methodObject = null;
Object result = null;
try{
methodObject = validate(clazz, methodName, args);
}
catch(NoSuchMethodException ex){
throw ex;
}
catch(ClassNotFoundException e){
throw e;
}
if (Modifier.isStatic(methodObject.getModifiers())) {
result = methodObject.invoke(null, args);
}
else{
result = methodObject.invoke(clazz, args);
}
return (result == null ? VOID : result);
}
}
f. 映射类:映射数据和类对象。(BeanLoader)
BeanLoader.java
public interface BeanLoader {
Object loadBean(String beanName) throws BeanLoadException;
}
g. 代理类:生成代理对象。(DynamicProxy)
public class DynamicBeanProxy extends DynamicProxy implements InvocationHandler{
protected Object obj;
private DynamicAopProxy(Object targetObject) {
this.obj = targetObject;
}
public Object invoke(Object proxy, Method m, Object[] args) throws Throwable {
Object result;
try{
result = advice.proceed(obj,m,args);
}
catch (Exception e) {
e.printStackTrace();
throw new RuntimeException
("unexpected invocation exception: " + e.getMessage());
}
finally {
System.out.println("end method " + m.getName());
}
return result;
}
public static Object newInstance(Object obj) throws FatalProxyException {
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
obj.getClass().getInterfaces(),new DynamicBeanProxy(obj));
}
}
h. 上下文环境类:提供上下文环境。(Appliction, Context, Session)
public interface Application {
Object getInstance(String beanName);
Object getProxyInstance(String className);
Context getContext();
}
public interface Config {
public Object getValue(String key) throws ConfigException;
}
public abstract class Context {
public static Application getAppliation(){
return null;
}
public static Config getConfig(){
return null;
}
public static Session getSession(){
return null; }
}
2.3 补充说明:
本系统容器,由于目前开发的迭代状态,在当前版本的实现中提供如下特性:
a. IoC Type2实现。 即使用java的setter实现。
b. 组件的生命周期目前只实现了Singleton。
在未来版本的迭代中,将提供三大性能技术:
a. Pooling实现。容器将提供池化机制,提高系统性能。
b. Virtual Proxy完整实现。容器提供虚实例机制,采用Lazy reference,提高系统性能。
c. Cache完整实现。容器提供缓存机制,提高系统总体性能。
2.3.2 AOP容器
1. AOP介绍
面向Aspect的编程(AOP)是一种新的编程技术,它允许开发人员对横切关系(crosscutting concerns)(跨越典型职责界限的行为,例如日志记录)进行模块化。它有助于解决紧密耦合的难题。
AOP有如下概念:
• Aspect(方面):一个模块化的横切关注点。如事务处理。
• Joinpoint(连接点):是程序执行中的一个精确执行点,比如类的一个方法。分dynamic-join points 和static-join points。
• Advice(通知):是切入点的可执行代码。有四种类型。
• Pointcut(切入点):本质上一个捕捉连接点的结构。是advice的激发条件——一组特定连接点集合。一个AOP框架允许开发人员定义切入点,特别的使用正则表达式。.
• Target object(目标对象):包含切入点的对象。
• AOP proxy(AOP代理):由AOP框架创建的包含通知的代理对象。一个AOP代理可以是JDK动态代理或者是GLIB代理。
通知的四种类型如下:
Around advice:
Advice that surrounds a joinpoint such as a method invocation. This is the most powerful kind of advice. Around advices will perform custom behaviour before and after the method invocation. They are responsible for choosing whether to proceed to the joinpoint or to shortcut executing by returning their own return value or throwing an exception.
Before advice:
Advice that executes before a joinpoint, but which does not have the ability to prevent execution flow proceeding to the joinpoint
Throws advice:
Advice to be executed if a method throws an exception.
After returning advice
Advice to be executed after a joinpoint completes normally: for example, if a method returns without throwing an exception.
2. AOP目前有三种实现途径:
a、类似AspectJ
使用特定的语法将代码插入到相应代码中的过程,一般是编译完成在编译时修改java类代码实现,interception and introduct 等;
b、类似JBossAOP
在类加载时利用反射机制实现AOP的功能;
c、类似nanning
使用java 动态代理。
3. AOP容器实现:
本系统使用java的动态代理机制调度拦截器实现。
其整体运行环境架构如下图:
3.1 AOP容器的工作方式:
技术上基本上分为三个部分:
a. 读取XML配置文件信息
读取配置信息并映射到连接点信息对象。
b. 管理方面
根据连接点信息对象组装合适切入点对象。
c. 创建AOP代理
其工作方式运行如下: