为了能更为深入理解Spring原理,知道怎么用还不如会自己做,于是便动手完成了这个集成框架。功能点仿照Spring,包括IOC中的注入、延迟加载、装配集合等等一系列功能,AOP是采用jdk动态代理实现的,没用CGLIB,因此,被代理的对象必须继承某个接口。
源代码主要为:
ConfigManager.java 负责解析xml、装配bean、获取bean等操作,是框架最重要的类。
ParserHelper.java 辅助XML解析的类。
ProxyHandler.java 代理类,用于支持AOP功能。
ProceedingJoinPoint.java 为了能够实现代理链,封装了Method、Object、args对象以及execute()方法。
AspectInfo.java 切面信息对象。
autumn.dtd DTD文件,用于约束配置文件语法。
源码如下:
ConfigManager.java
package cn.seu.bingluo.ioc; import java.lang.reflect.InvocationTargetException; /* * By Bingluo 2012.8.17 * cose.seu.edu.cn */ public class ConfigManager { // 存放dom private Document dom; private Element root; // 从配置中生成的bean放入map中 private HashMap<String, Object> beans = new HashMap<String, Object>(); // 在构造函数时,初始化dom树 public ConfigManager(String xmlUrl) { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); factory.setIgnoringElementContentWhitespace(true); DocumentBuilder db; try { db = factory.newDocumentBuilder(); dom = db.parse(xmlUrl); dom.normalize(); root = dom.getDocumentElement(); System.out.println("IOC/AOP初始化开始..."); initBeans(); System.out.println("IOC/AOP初始化结束..."); } catch (Exception e) { e.printStackTrace(); } } // 初始化配置文件中所有非懒加载的bean private void initBeans() { for (Node node = root.getFirstChild(); node != null; node = node .getNextSibling()) { // 延迟加载Bean if (node.getNodeName().equals("bean") && ((Element) node).hasAttribute("lazy-init") && ((Element) node).getAttribute("lazy-init") .equals("true")) continue; else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("bean")) // 普通bean // 创建后,存入map中 beans.put(((Element) node).getAttribute("id"), initBean(node)); else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("aop-config")) { // aop配置 initAOP(node); } } } //AOP配置 private void initAOP(Node aopConfig) { for (Node node = aopConfig.getFirstChild(); node != null; node = node .getNextSibling()) { // 为切面节点,配置增强 if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("aspect")) { initAspect(node); } } } //配置AOP切面 private void initAspect(Node aspect) { String aspectRef = ((Element) aspect).getAttribute("ref"); Object adviceBean = null; String expression = ""; Method beforeMethod = null; Method aroundMethod = null; Method afterMethod = null; if (beans.containsKey(aspectRef)) { // 在beans的map中发现已初始化过该bean adviceBean = beans.get(aspectRef); } else { // 未初始化过该bean Node e = dom.getElementById(aspectRef); if (e.getNodeName().equals("bean")) { // 递归调用,初始化被引用的bean adviceBean = initBean(e); } } // 获取切点 // ***************1个切面默认最多只有1个切点、1个前置增强、1个后置增强、1个环绕增强 Node pointcutNode = ParserHelper.getNode(aspect, "pointcut"); expression = ((Element) pointcutNode).getAttribute("expression"); // 获取该切面的增强 for (Node currentNode = aspect.getFirstChild(); currentNode != null; currentNode = currentNode .getNextSibling()) { if (currentNode.getNodeType() != Node.ELEMENT_NODE) continue; // 为相应的增强赋值 String methodName = ((Element) currentNode).getAttribute("method"); try { if (currentNode.getNodeName().equals("before")) { beforeMethod = adviceBean.getClass().getMethod(methodName); } else if (currentNode.getNodeName().equals("around")) { aroundMethod = adviceBean.getClass().getMethod(methodName, ProceedingJoinPoint.class); } else if (currentNode.getNodeName().equals("after")) { afterMethod = adviceBean.getClass().getMethod(methodName); } } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } } // 将该切面交给代理维护 AspectInfo aspectInfo = new AspectInfo(expression, adviceBean, beforeMethod, aroundMethod, afterMethod); ProxyHandler.addAspectInfo(aspectInfo); } //初始化Bean @SuppressWarnings({ "rawtypes", "unchecked" }) private Object initBean(Node node) { // 初始化的类型 Class c = null; // 需要初始化的bean Object object = null; // 生成对象 try { c = Class.forName(((Element) node).getAttribute("class")); object = c.newInstance(); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } // 如果此bean为基本类型bean if (isPrimitive(((Element) node).getAttribute("class")) || ((Element) node).hasAttribute("value")) { object = getInstanceForName(((Element) node).getAttribute("class"), ((Element) node).getAttribute("value")); return object; } boolean constructorInit = false;// 是否为构造函数注入 ArrayList<Class> parameterTypes = new ArrayList<Class>(); ArrayList<Object> parameters = new ArrayList<Object>(); // 为bean配置属性 for (Node property = node.getFirstChild(); property != null; property = property .getNextSibling()) { if (property.getNodeType() != Node.ELEMENT_NODE) { continue; } if (property.getNodeName().equals("constructor-arg")) { // bean为构造函数注入 constructorInit = true; if (((Element) property).hasAttribute("value")) { // 该参数为基本类型参数 getInstanceForName( ((Element) property).getAttribute("type"), ((Element) property).getAttribute("value")); Class temp = nameToPrimitiveClass(((Element) property) .getAttribute("type")); parameterTypes.add(temp); parameters.add(getInstanceForName( ((Element) property).getAttribute("type"), ((Element) property).getAttribute("value"))); } else if (((Element) property).hasAttribute("ref")) { String refId = ((Element) property).getAttribute("ref"); // 该参数为外部bean引用属性 if (beans.containsKey(refId)) { // 在beans的map中发现已初始化过该bean parameterTypes.add(beans.get(refId).getClass()); parameters.add(beans.get(refId)); } else { // 未初始化过该bean Node e = dom.getElementById(refId); if (e.getNodeName().equals("bean")) { // 递归调用,初始化被引用的bean Class temp = null; try { temp = Class.forName(((Element) e) .getAttribute("class")); } catch (ClassNotFoundException e1) { e1.printStackTrace(); } parameterTypes.add(temp); parameters.add(initBean(e)); } } } } else if (property.getNodeName().equals("property")) { // bean为普通属性注入 String propertyName = ((Element) property).getAttribute("name"); // 获取该属性对应的set方法 Method[] methods = c.getMethods(); Method method = null; for (int k = 0; k < methods.length; k++) { if (methods[k].getName().equalsIgnoreCase( "set" + propertyName)) { method = methods[k]; } } Object value = null;// 属性值 if (((Element) property).hasAttribute("value")) { // 该属性为直接属性,非外部bean引用属性 String propertyValue = ((Element) property) .getAttribute("value"); Class<?>[] types = method.getParameterTypes(); value = getInstanceForName(types[0].getName(), propertyValue); } else if (((Element) property).hasAttribute("ref")) { String refId = ((Element) property).getAttribute("ref"); // 该属性为外部bean引用属性 if (beans.containsKey(refId)) { // 在beans的map中发现已初始化过该bean value = beans.get(refId); } else { // 未初始化过该bean Node e = dom.getElementById(refId); if (e.getNodeName().equals("bean")) { // 递归调用,初始化被引用的bean value = initBean(e); } } } else if (ParserHelper.containNode(property, "bean")) { // 该属性为内部bean引用属性 Node innerBeanNode = null; for (innerBeanNode = property.getFirstChild(); innerBeanNode != null; innerBeanNode = innerBeanNode .getNextSibling()) { if (innerBeanNode.getNodeName().equals("bean")) { break; } } value = initBean(innerBeanNode); } else if (ParserHelper.containNode(property, "list") || ParserHelper.containNode(property, "set")) { // 属性为list、set集合类型 Collection<Object> collection = ParserHelper.containNode( property, "list") ? new ArrayList<Object>() : new HashSet(); for (Node currentNode = property.getFirstChild() .getFirstChild(); currentNode != null; currentNode = currentNode .getNextSibling()) { if (currentNode.getNodeName().equals("ref") && (((Element) currentNode) .hasAttribute("bean") && beans .containsKey(((Element) currentNode) .getAttribute("bean")))) { // 该list子元素为引用bean String ref = ((Element) currentNode) .getAttribute("bean"); collection.add(beans.get(ref)); } else if (currentNode.getNodeName().equals("bean")) { // 该list子元素为内部bean collection.add(initBean(currentNode)); } } value = collection; } else if (ParserHelper.containNode(property, "map")) { // 属性为map集合类型 HashMap<String, Object> map = new HashMap<String, Object>(); for (Node currentNode = property.getFirstChild() .getFirstChild(); currentNode != null; currentNode = currentNode .getNextSibling()) { if (currentNode.getNodeName().equals("entry") && (((Element) currentNode).hasAttribute("key") && (((Element) currentNode) .hasAttribute("value-ref") && beans .containsKey(((Element) currentNode) .getAttribute("value-ref"))))) { // 该list子元素为引用bean String key = ((Element) currentNode) .getAttribute("key"); String ref = ((Element) currentNode) .getAttribute("value-ref"); map.put(key, beans.get(ref)); } } value = map; } else if (ParserHelper.containNode(property, "props")) { // 属性为props属性类型 Properties props = new Properties(); for (Node currentNode = property.getFirstChild() .getFirstChild(); currentNode != null; currentNode = currentNode .getNextSibling()) { if (currentNode.getNodeName().equals("prop") && ((Element) currentNode).hasAttribute("key")) { // 该list子元素为引用bean String key = ((Element) currentNode) .getAttribute("key"); String propValue = currentNode.getTextContent(); props.setProperty(key, propValue); } } value = props; } // 调用set方法,初始化bean的属性 try { method.invoke(object, value); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } // 若为构造函数注入 if (constructorInit == true) { Class[] aClasses = {}; Class[] classes = (Class[]) parameterTypes.toArray(aClasses); Object[] prams = (Object[]) parameters.toArray(); try { object = c.getConstructor(classes).newInstance(prams); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } if (object.getClass().getInterfaces().length == 0) { return object; } else { // 返回经过代理的bean return new ProxyHandler(object).getProxyInstance(); } } // 获取hashMap中相应的bean public Object getBean(String id) { Object bean = beans.get(id); // 未初始化的bean,有可能为懒加载,也有可能没有此bean if (bean == null) { Element element = dom.getElementById(id); if (element.getTagName().equals("bean") && element.hasAttribute("lazy-init") && element.getAttribute("lazy-init").equals("true")) { // 确实为懒加载 // 创建后,存入map中 System.out.println("懒加载:" + id); bean = initBean(element); beans.put(element.getAttribute("id"), bean); } else { // 无此Bean的懒加载声明 System.out.println("找不到此Bean"); } } return bean; } // 检验是否为基本值类型或基本对象 @SuppressWarnings("rawtypes") private boolean isPrimitive(String className) { Class clazz = null; try { clazz = Class.forName(className); } catch (ClassNotFoundException e) { e.printStackTrace(); } String name = clazz.getName(); if (clazz.isPrimitive() || name.equals("java.lang.String") || name.equals("java.lang.Integer") || name.equals("java.lang.Float") || name.equals("java.lang.Double") || name.equals("java.lang.Character") || name.equals("java.lang.Integer") || name.equals("java.lang.Boolean") || name.equals("java.lang.Short")) { return true; } else { return false; } } // 通过字符串反射类型,增加了对基本类型的包装 @SuppressWarnings({ "rawtypes", "unchecked" }) private Object getInstanceForName(String name, String value) { Class clazz = nameToClass(name); Object object = null; try { object = clazz.getConstructor(String.class).newInstance(value); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } return object; } //通过类型名返回基本类型Class(Class.forName()貌似不行) @SuppressWarnings("rawtypes") private Class nameToPrimitiveClass(String name) { Class clazz = null; if (name.equals("int")) { clazz = int.class; } else if (name.equals("char")) { clazz = char.class; } else if (name.equals("boolean")) { clazz = boolean.class; } else if (name.equals("short")) { clazz = short.class; } else if (name.equals("long")) { clazz = long.class; } else if (name.equals("float")) { clazz = float.class; } else if (name.equals("double")) { clazz = double.class; } else if (name.equals("byte")) { clazz = byte.class; } else { try { clazz = Class.forName(name); } catch (ClassNotFoundException e) { e.printStackTrace(); } } return clazz; } //通过类型名获取包装器类 @SuppressWarnings("rawtypes") private Class nameToClass(String name) { Class clazz = null; if (name.equals("int")) { clazz = Integer.class; } else if (name.equals("char")) { clazz = Character.class; } else if (name.equals("boolean")) { clazz = Boolean.class; } else if (name.equals("short")) { clazz = Short.class; } else if (name.equals("long")) { clazz = Long.class; } else if (name.equals("float")) { clazz = Float.class; } else if (name.equals("double")) { clazz = Double.class; } else if (name.equals("byte")) { clazz = Byte.class; } else { try { clazz = Class.forName(name); } catch (ClassNotFoundException e) { e.printStackTrace(); } } return clazz; } }
ParserHelper.java
package cn.seu.bingluo.ioc;
import org.w3c.dom.Node;
/*
* By Bingluo 2012.8.17
* cose.seu.edu.cn
* Parser辅助方法
*/
public class ParserHelper {
//查看Node中是否存在名为name的子节点
public static boolean containNode(Node node,String name){
for (Node currentNode = node.getFirstChild(); currentNode!=null; currentNode = currentNode.getNextSibling()) {
if (currentNode.getNodeName().equals(name)) {
return true;
}
}
return false;
}
//返回名称对应的节点
public static Node getNode(Node node, String name){
for (Node currentNode = node.getFirstChild(); currentNode!=null; currentNode = currentNode.getNextSibling()) {
if (currentNode.getNodeName().equals(name)) {
return currentNode;
}
}
return null;
}
}
ProxyHandler.java
package cn.seu.bingluo.ioc; import java.lang.reflect.InvocationHandler; /* * 代理类 * 运用jdk动态代理实现,要求前提是被代理对象实现接口 */ public class ProxyHandler implements InvocationHandler { // 存储所有切面 private static HashMap<String, AspectInfo> aspectInfos = new HashMap<String, AspectInfo>(); // 被代理的对象 private Object target = null; public ProxyHandler(Object target) { this.target = target; } public static void addAspectInfo(AspectInfo aspectInfo) { aspectInfos.put(aspectInfo.getExpression(), aspectInfo); } // 获取代理实例 public Object getProxyInstance() { if (target == null) { return null; } return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } // 获取代理实例 public Object getProxyInstance(Object target) { if (target == null) { return null; } this.target = target; return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { ArrayList<AspectInfo> aspects = new ArrayList<AspectInfo>(); Set<Entry<String, AspectInfo>> entrySet = aspectInfos.entrySet(); Object result = null; //遍历切面列表,找到对应的切面 for (Entry<String, AspectInfo> entry : entrySet) { AspectInfo aspectInfo = entry.getValue(); Object adviceBean = aspectInfo.getAdviceBean(); String expression = aspectInfo.getExpression(); Pattern pattern = Pattern.compile(expression); Matcher matcher = pattern.matcher(target.getClass().getName() + "." + method.getName()); if (matcher.find()) { AspectInfo aspect = new AspectInfo(); aspect.setAdviceBean(adviceBean); aspect.setBeforeMethod(aspectInfo.getBeforeMethod()); aspect.setAroundMethod(aspectInfo.getAroundMethod()); aspect.setAfterMethod(aspectInfo.getAfterMethod()); aspects.add(aspect); } } // 执行before增强 for (AspectInfo aspect : aspects) { Object adviceBean = aspect.getAdviceBean(); if (aspect.getBeforeMethod() != null) { aspect.getBeforeMethod().invoke(adviceBean, new Object[]{}); } } // 执行around增强 Object aroundAdviceBean = target; Method aroundAdviceMethod = method; Object[] aroundAdviceArgs = args; for (AspectInfo aspect : aspects) { Object adviceBean = aspect.getAdviceBean(); if (aspect.getAroundMethod() != null) { aroundAdviceArgs = new Object[] { new ProceedingJoinPoint( aroundAdviceBean, aroundAdviceMethod, aroundAdviceArgs) }; aroundAdviceBean = adviceBean; aroundAdviceMethod = aspect.getAroundMethod(); } } result = aroundAdviceMethod.invoke(aroundAdviceBean, aroundAdviceArgs); // 执行After增强 for (AspectInfo aspect : aspects) { Object adviceBean = aspect.getAdviceBean(); if (aspect.getAfterMethod() != null) { aspect.getAfterMethod().invoke(adviceBean, new Object[]{}); } } return result; } }
ProceedingJoinPoint.java
package cn.seu.bingluo.ioc; import java.lang.reflect.InvocationTargetException; /* * 用于处理AOP代理链时,封装相关信息作为统一参数进行传递 */ public class ProceedingJoinPoint { private Object object;//被代理的对象 private Method method;//被代理的方法 private Object[] args;//方法相应的参数 public ProceedingJoinPoint(Object object, Method method, Object[] args){ this.object = object; this.method = method; this.args = args; } //执行目标函数 public Object excute(){ Object result = null; try { result = method.invoke(object, args); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } return result; } }
AspectInfo.java
package cn.seu.bingluo.ioc; import java.lang.reflect.Method; /* * 切面信息Bean * 每1个切面最多只有: * 1个切点expression * 1个增强bean * 1个前置增强、环绕增强、后置增强 */ public class AspectInfo { private String expression = ""; private Object adviceBean = null; private Method beforeMethod = null; private Method aroundMethod = null; private Method afterMethod = null; public AspectInfo(){ } public AspectInfo(String expression, Object adviceBean, Method beforeMethod, Method aroundMethod, Method afterMethod) { setExpression(expression); setAdviceBean(adviceBean); setBeforeMethod(beforeMethod); setAroundMethod(aroundMethod); setAfterMethod(afterMethod); } public String getExpression() { return expression; } public void setExpression(String expression) { this.expression = expression; } public Object getAdviceBean() { return adviceBean; } public void setAdviceBean(Object adviceBean) { this.adviceBean = adviceBean; } public Method getBeforeMethod() { return beforeMethod; } public void setBeforeMethod(Method beforeMethod) { this.beforeMethod = beforeMethod; } public Method getAroundMethod() { return aroundMethod; } public void setAroundMethod(Method aroundMethod) { this.aroundMethod = aroundMethod; } public Method getAfterMethod() { return afterMethod; } public void setAfterMethod(Method afterMethod) { this.afterMethod = afterMethod; } }
autumn.dtd
<?xml version="1.0" encoding="GBK"?> <!ELEMENT beans (bean|aop-config)*> <!ELEMENT bean (property*|constructor-arg*)> <!ELEMENT aop-config (aspect*)> <!ELEMENT aspect (pointcut,before?,around?,after?)> <!ELEMENT property (bean|list|set|map|props)> <!ELEMENT list (ref*)> <!ELEMENT set (ref|bean)*> <!ELEMENT map (entry*)> <!ELEMENT props (prop*)> <!ELEMENT prop (#PCDATA)> <!ATTLIST bean id ID #IMPLIED> <!ATTLIST bean class CDATA #REQUIRED> <!ATTLIST bean value CDATA #IMPLIED> <!ATTLIST property name CDATA #REQUIRED> <!ATTLIST property value CDATA #IMPLIED> <!ATTLIST property ref IDREF #IMPLIED> <!ATTLIST constructor-arg type CDATA #IMPLIED> <!ATTLIST constructor-arg value CDATA #IMPLIED> <!ATTLIST constructor-arg ref IDREF #IMPLIED> <!ATTLIST ref bean IDREF #REQUIRED> <!ATTLIST entry key CDATA #REQUIRED> <!ATTLIST entry value-ref IDREF #REQUIRED> <!ATTLIST prop key CDATA #REQUIRED> <!ATTLIST aspect ref IDREF #REQUIRED> <!ATTLIST pointcut expression CDATA #REQUIRED> <!ATTLIST before method CDATA #REQUIRED> <!ATTLIST around method CDATA #REQUIRED> <!ATTLIST after method CDATA #REQUIRED>
接下来,我们来测试一下框架功能是否实现!
先测试IOC,测试bean的装配,写个POJO类
TestIOCBean.java
package cn.seu.bingluo.ioc; import java.util.Collection; /* * By Bingluo 2012.8.17 * cose.seu.edu.cn * 测试Bean */ public class TestIOCBean { private int a; private Integer aa; private String b; private TestIOCBean innerBean; private TestIOCBean outterBean; private Collection<String> collection; private Map<String, String> map; private Properties props; public TestIOCBean(){ } public TestIOCBean(int a,String b,TestIOCBean oBeanTest) { this.setA(a); this.setB(b); this.setOutterBean(oBeanTest); } public Integer getA() { return a; } public void setA(int a){ this.a = a; } public Integer getAa() { return aa; } public void setAa(Integer aa) { this.aa = aa; } public String getB() { return b; } public void setB(String b) { this.b = b; } public TestIOCBean getInnerBean() { return innerBean; } public void setInnerBean(TestIOCBean innerBean) { this.innerBean = innerBean; } public TestIOCBean getOutterBean() { return outterBean; } public void setOutterBean(TestIOCBean outterBean) { this.outterBean = outterBean; } public Collection<String> getCollection() { return collection; } public void setCollection(Collection<String> collection) { this.collection = collection; } public Map<String, String> getMap() { return map; } public void setMap(Map<String, String> map) { this.map = map; } public Properties getProps() { return props; } public void setProps(Properties props) { this.props = props; } }
再写一个Service类,用于测试AOP功能,注意,框架AOP功能是用JDK动态代理实现的,故必须继承自某个接口:
ITestAOPBean.java
package cn.seu.bingluo.ioc; /* * 必须被继承才能实现AOP代理 */ public interface ITestAOPBean { public int shout(); }
TestAOPBean.java
package cn.seu.bingluo.ioc; /* * 测试AOP功能 * 用jdk动态代理实现,故必须继承接口 */ public class TestAOPBean implements ITestAOPBean{ private String name = "aop-test"; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public int shout() { System.out.println("Hello, My name is "+name); return 1; } }
再为这个service写一个增强类,将该类中的方法织入service的shout()中。
Advice.java
package cn.seu.bingluo.ioc; /* * 增强类 * 用于测试AOP功能 */ public class Advice { public void Before(){ System.out.println("Before..."); } public Object Around(ProceedingJoinPoint joinPoint){ System.out.println("Before-around..."); Object object = joinPoint.excute(); System.out.println("After-around..."); return object; } public void After(){ System.out.println("After..."); } }
到这里,重点来了,我们就需要将bean配置起来了,建立xml文件:
config.xml(注意用dtd约束)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans SYSTEM "d:\\autumn.dtd"> <beans> <bean id="str1" class="java.lang.String" value="String: str1"/> <bean id="str2" class="java.lang.String" value="String: str2"/> <bean id="bean" class="cn.seu.bingluo.ioc.TestIOCBean" lazy-init="true"> <property name="a" value="1000" /> <property name="aa" value="999" /> <property name="b" value="I'm lazy-init bean" /> <property name="innerBean"> <bean class="cn.seu.bingluo.ioc.TestIOCBean"> <property name="a" value="1000" /> <property name="aa" value="999" /> <property name="b" value="I'm inner bean" /> <property name="outterBean" ref="outterBean" /> <property name="collection"> <set> <ref bean="str1" /> <bean class="java.lang.String" value="str3" /> </set> </property> </bean> </property> <property name="collection"> <list> <ref bean="str1" /> <ref bean="str2" /> </list> </property> </bean> <bean id="outterBean" class="cn.seu.bingluo.ioc.TestIOCBean"> <property name="a" value="1000" /> <property name="aa" value="999" /> <property name="b" value="I'm outter bean" /> <property name="map"> <map> <entry key="s1" value-ref="str1" /> <entry key="s2" value-ref="str2" /> </map> </property> <property name="props"> <props> <prop key="s3">im' props' value: s3</prop> <prop key="s4">im' props' value: s4</prop> </props> </property> </bean> <bean id="constructorInit" class="cn.seu.bingluo.ioc.TestIOCBean"> <constructor-arg value="555" type="int" /> <constructor-arg value="String" type="java.lang.String" /> <constructor-arg ref="bean" /> </bean> <bean id="shoutBean" class="cn.seu.bingluo.ioc.TestAOPBean" /> <bean id="adviceBean" class="cn.seu.bingluo.ioc.Advice" /> <!-- AOP配置 --> <aop-config> <!-- 定义切面 --> <aspect ref="adviceBean"> <!-- 定义切点 --> <pointcut expression=".*.shout()" /> <!-- 定义各类增强 --> <before method="Before" /> <around method="Around" /> <after method="After" /> </aspect> </aop-config> </beans>
最后,再写一个main函数驱动一下,就大功告成啦!
Driver.java
package cn.seu.bingluo.ioc; import java.util.Iterator; public class Driver { /** * @param args */ @SuppressWarnings("rawtypes") public static void main(String[] args) { // 测试桩 // 解析IOC配置文件 ConfigManager configManager = new ConfigManager("config.xml"); // 获取id为“bean”的Bean TestIOCBean beanTest = (TestIOCBean) configManager.getBean("bean"); System.out.println(beanTest.getA() + ":" + beanTest.getAa() + ":" + beanTest.getB()); System.out.println(beanTest.getInnerBean().getB()); System.out.println(beanTest.getInnerBean().getOutterBean().getB()); String string = (String) configManager.getBean("str1"); System.out.println(string); string = (String) configManager.getBean("str2"); System.out.println(string); // 装配集合测试 List<String> list = (List<String>) beanTest.getCollection(); System.out.println(list.get(0)); Set<String> set = (Set<String>) beanTest.getInnerBean().getCollection(); for (Iterator it = set.iterator(); it.hasNext();) { System.out.println("value=" + it.next().toString()); } TestIOCBean outterBeanTest = (TestIOCBean) configManager .getBean("outterBean"); System.out.println(outterBeanTest.getMap().get("s1")); System.out.println(outterBeanTest.getProps().get("s3")); //测试构造函数注入 TestIOCBean constructorBeanTest = (TestIOCBean) configManager .getBean("constructorInit"); System.out.println(constructorBeanTest.getA() + constructorBeanTest.getB() + constructorBeanTest.getOutterBean().getAa()); //测试AOP功能 System.out.println("\n***************** AOP测试 *****************"); ITestAOPBean testBean = (ITestAOPBean) configManager.getBean("shoutBean"); testBean.shout(); } }
运行结果:
功能算是实现啦!
如果有发现什么问题或者不足的话,欢迎给我留言或者发送邮件。谢谢!
邮箱:bingluo#foxmail.com(#转为@)