爲了能更爲深刻理解Spring原理,知道怎麼用還不如會本身作,因而便動手完成了這個集成框架。功能點仿照Spring,包括IOC中的注入、延遲加載、裝配集合等等一系列功能,AOP是採用jdk動態代理實現的,沒用CGLIB,所以,被代理的對象必須繼承某個接口。 java
源代碼主要爲: node
ConfigManager.java 負責解析xml、裝配bean、獲取bean等操做,是框架最重要的類。 express
ParserHelper.java 輔助XML解析的類。 框架
ProxyHandler.java 代理類,用於支持AOP功能。 dom
ProceedingJoinPoint.java 爲了可以實現代理鏈,封裝了Method、Object、args對象以及execute()方法。 ide
AspectInfo.java 切面信息對象。 函數
autumn.dtd DTD文件,用於約束配置文件語法。 測試
源碼以下: ui
ConfigManager.java this
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(#轉爲@)