Spring解析实践

这几天重新把传智播客的黎活明的Spring2.5的教程学习了一遍,跟着上面的解析Spring的过程跟着制作了一个简单的Spring IOC和Spring AOP,先在贴上来给大家参考一下。

1:管理Bean和依赖注入 配制文件bean.xml格式如下模板所示:

<?xml version="1.0" encoding="UTF-8"?>   
<beans xmlns="http://www.ganggang.com/beans">  
  
      
    <bean id="personDao" class="com.ganggang.dao.impl.PersonDaoImpl">  
      
    </bean>  
    <bean id="personService" class="com.ganggang.service.impl.PersonServiceImpl">  
        <property name="no" value="0704685003"/>  
    </bean>  
</beans>  

  用一个名为XmlApplication的类从bean.xml中读取相应的bean的配制信息并根据需要返回想要实例化的bean的实例对象。

public class XmlApplication {  
    private List<BeanDefinition> beans=new ArrayList<BeanDefinition>();  
    private Map<String,Object> objs=new HashMap<String, Object>();  
    public XmlApplication(String file){  
        this.readXml(file);  
        this.instance();  
        this.annotationInject();  
        this.injectObject();  
                ................    }  
}  

  XmlApplication对象实例化时,先用readXml函数读取bean.xml中的bean配置信息,将每个bean实例化成BeanDefinition对象并存储在名为beans的链表中,BeanDefinition定义如下:

public class BeanDefinition {  
    private String id;  
    private String className;  
    private List<PropertyDefinition> propertys=new ArrayList<PropertyDefinition>();  
      
    public BeanDefinition(String id, String className) {  
        this.id = id;  
        this.className = className;  
    }  
    ...........getter和setter方法  
  
}  

  BeanDefinition中的propertys用来表示每个bean中的属性,每个属性即是一个PropertyDefinition型对象,PropertyDefinition定义如下:

public class PropertyDefinition {  
    private String name;  
    private String ref;  
    private String value;  
      
    public PropertyDefinition(String name, String ref,String value) {  
        this.name = name;  
        this.ref = ref;  
        this.value=value;  
    }  
.................getter和setter方法  
}  

  readXml函数的代码如下:

private void readXml(String file) {  
         SAXReader saxReader = new SAXReader();     
            Document document=null;     
            try{  
             URL xmlpath = this.getClass().getClassLoader().getResource(file);  
             document = saxReader.read(xmlpath);  
             Map<String,String> nsMap = new HashMap<String,String>();  
             nsMap.put("ns","http://www.ganggang.com/beans");//加入命名空间  
             XPath xsub = document.createXPath("//ns:beans/ns:bean");//创建beans/bean查询路径  
             xsub.setNamespaceURIs(nsMap);//设置命名空间  
             List<Element> beanss = xsub.selectNodes(document);//获取文档下所有bean节点   
             for(Element element: beanss){  
                String id = element.attributeValue("id");//获取id属性值  
                System.out.println(id);  
                String clazz = element.attributeValue("class"); //获取class属性值          
                BeanDefinition beanDefine = new BeanDefinition(id, clazz);  
                //开始处理property  
                XPath propertysub=element.createXPath("ns:property");  
                propertysub.setNamespaceURIs(nsMap);  
                List<Element> props=propertysub.selectNodes(element);  
                for(Element e:props){  
                    String name=e.attributeValue("name");  
                    String ref=e.attributeValue("ref");  
                    String val=e.attributeValue("value");  
                    PropertyDefinition propertyDefinition=new PropertyDefinition(name,ref,val);  
                    beanDefine.getPropertys().add(propertyDefinition);  
                    System.out.println("name:"+name+";value:"+val);  
                }  
                //除了你property完毕  
                beans.add(beanDefine);  
             }     
            }catch(Exception e){     
                e.printStackTrace();  
            }  
    }  

  然后,XmlApplication再调用instance方法实例化beans中的bean,并将每个bean对象存储在map型的objs中,objs中的key即为每个bean的id。

private void instance() {  
        for(BeanDefinition bean:beans){  
            try {  
                objs.put(bean.getId(), Class.forName(bean.getClassName()).newInstance());  
                System.out.println(bean.getId());  
            } catch (InstantiationException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            } catch (IllegalAccessException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            } catch (ClassNotFoundException e) {  
                // TODO Auto-generated catch block  
                e.printStackTrace();  
            }  
        }  
          
    }  

  最后进行依赖注入,本程序同时支持注解注入和xml配制文件注入,根据实际需要选择注入方式。其中annotationInject函数执行注解注入,injectObject函数执行配制文件注入。代码如下:

private void annotationInject() {  
        for(String beanName:objs.keySet()){  
            Object bean=objs.get(beanName);  
            if(bean!=null){  
                try {  
                    PropertyDescriptor[] ps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();  
                    for(PropertyDescriptor properdesc:ps){  
                        Method setter=properdesc.getWriteMethod();  
                        if(setter!=null&&setter.isAnnotationPresent(Resource.class)){  
                            Resource resource=setter.getAnnotation(Resource.class);  
                            Object value=null;  
                            if(resource.name()!=null&&!"".equals(resource.name())){  
                                value=objs.get(resource.name());  
                                  
                            }else{  
                                value=objs.get(properdesc.getName());  
                                if(value==null){  
                                    for(String key:objs.keySet()){  
                                        if(properdesc.getPropertyType().isAssignableFrom(objs.get(key).getClass())){  
                                            value=objs.get(key);  
                                            break;  
                                        }  
                                    }  
                                }  
                            }  
                            setter.setAccessible(true);  
                            setter.invoke(bean, value);  
                        }  
                    }  
                    Field[] fields= bean.getClass().getDeclaredFields();  
                    for(Field field:fields){  
                        if(field.isAnnotationPresent(Resource.class)){  
                            Resource resource=field.getAnnotation(Resource.class);  
                            Object value=null;  
                            if(resource.name()!=null&&!"".equals(resource.name())){  
                                value=objs.get(resource.name());  
                                  
                            }else{  
                                value=objs.get(field.getName());  
                                if(value==null){  
                                    for(String key:objs.keySet()){  
                                        if(field.getType().isAssignableFrom(objs.get(key).getClass())){  
                                            value=objs.get(key);  
                                            break;  
                                        }  
                                    }  
                                }  
                            }  
                            field.setAccessible(true);  
                            field.set(bean, value);  
                        }  
                    }  
                } catch (Exception e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
            }  
        }  
          
    }  
    private void injectObject() {  
        for(BeanDefinition beanDefinition:beans){  
            Object bean=objs.get(beanDefinition.getId());  
            if(bean!=null){  
                try {  
                    PropertyDescriptor[] ps=Introspector.getBeanInfo(bean.getClass()).getPropertyDescriptors();  
                    for(PropertyDefinition propertyDefinition:beanDefinition.getPropertys()){  
                        for(PropertyDescriptor properdesc:ps){  
                            if(propertyDefinition.getName().equals(properdesc.getName())){  
                                Method setter= properdesc.getWriteMethod();  
                                if(setter!=null){  
                                    Object value=null;  
                                    if(propertyDefinition.getRef()!=null&&!"".equals(propertyDefinition.getRef().trim())){  
                                        value=objs.get(propertyDefinition.getRef());  
                                      
                                    }else{  
                                        value=ConvertUtils.convert(propertyDefinition.getValue(), properdesc.getPropertyType());  
                                    }  
                                    setter.setAccessible(true);  
                                    setter.invoke(bean, value);  
                                }  
                                break;  
                            }  
                        }  
                    }  
                } catch (Exception e) {  
                    // TODO Auto-generated catch block  
                    e.printStackTrace();  
                }  
                  
            }  
        }  
          
    }  

  

注入函数遍历beans中的每一个bean,如果其中有相应的property需要注入,就从objs中取得相应的实例对象注入。

XmlApplication含有一个获取相应bean的实力的函数,名为getObj,代码如下:

public Object getObj(String id){  
        return objs.get(id);  
    }  

  

您只需在bean.xml中配制相应的bean就可以实例化一个XmlApplication对象调用getObj函数控制反转出相应的Bean的实例。

2.动态代理实现AOP

   有两种,JDKProxy实现动态代理和CGLib实现。

   JDKProxy实现的代码如下:

public class JDKProxyFactory implements InvocationHandler{  
    private Object targetObject;  
      
    public Object createProxyInstance(Object targetObject){  
        this.targetObject=targetObject;  
        return Proxy.newProxyInstance(this.targetObject.getClass().getClassLoader(),   
                            this.targetObject.getClass().getInterfaces(),  
                            this);  
          
    }  
  
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {  
        PersonServiceBean bean=(PersonServiceBean)this.targetObject;  
        Object result=null;  
        if(bean.getUser()!=null){  
            result=method.invoke(targetObject, args);  
        }  
        return result;  
    }  
  
}  

  CGLib实现的代码如下:

 

public class CGligProxyFactory implements MethodInterceptor{  
    private Object targetObject;  
      
    public Object createProxyInstance(Object targetObject){  
        this.targetObject=targetObject;  
        Enhancer enhancer=new Enhancer();  
        enhancer.setSuperclass(this.targetObject.getClass());  
        enhancer.setCallback(this);  
        return enhancer.create();  
    }  
  
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {  
        PersonServiceBean bean=(PersonServiceBean)this.targetObject;  
        Object result=null;  
        if(bean.getUser()!=null){  
            result=methodProxy.invoke(targetObject, args);  
        }  
        return null;  
    }  

  

 

转载于:https://www.cnblogs.com/qingwengang/p/5972594.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值