为了能更为深入理解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(#转为@)