`
qingwengang
  • 浏览: 29079 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

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;
	}
	

 

霹雳猿教程_霹雳猿教程-HTML教程-HTML 教程

霹雳猿教程_霹雳猿教程-HTML教程-HTML 简介

霹雳猿教程_霹雳猿教程-HTML教程-HTML 基础

霹雳猿教程_霹雳猿教程-HTML教程-HTML 元素

霹雳猿教程_霹雳猿教程-HTML教程-HTML 属性

霹雳猿教程_霹雳猿教程-HTML教程-HTML 标题

分享到:
评论
2 楼 qingwengang 2010-05-03  
本来有的,先在不知道搞哪儿去了,不好意思啊。。。。
1 楼 五月天 2010-04-12  
强啊!小弟基础不好,能否附上源代码?还有加点注释。

相关推荐

    Spring 解析

    在"Spring 解析"这个主题中,我们将深入探讨Spring框架的各个方面。 1. **依赖注入(Dependency Injection, DI)** - 依赖注入是Spring的核心,它允许我们解耦组件间的依赖关系,使代码更易于测试和维护。 - 通过...

    Spring解析.7z

    《Spring源码深度解析》是针对Java开发人员深入理解Spring框架的重要参考资料。Spring作为一个广泛应用的开源框架,其IoC(Inversion of Control)容器、AOP(Aspect Oriented Programming)面向切面编程以及Spring ...

    Spring 自定义注解的解析

    在Spring框架中,自定义注解的解析是一个强大的特性,允许开发者根据业务需求创建特定的注解,并在Spring容器启动时自动处理这些注解。本文将深入探讨如何在Spring环境中通过`component-scan`配置来处理自定义Java...

    Spring的jar包解析

    在Spring的jar包解析中,我们可以深入了解Spring框架的组成部分及其功能。 1. **spring.jar** - 这是Spring的主jar包,包含了所有模块的基本功能,但不包括特定于某些技术的库,如mock、aspects、portlet和...

    spring源码解析.xmind

    spring源码解析的,里面介绍了springIoc,springAop,用xmind来整理的,内容清晰,不一定完全正确,仅供参考,如有问题,希望大家私我,我修改,这个免费给大家修改了

    java 解析xml,模拟spring框架ioc

    本教程将深入探讨如何模拟Spring框架的IOC(Inversion of Control,控制反转)功能,特别关注XML配置文件的解析。 首先,我们需要理解什么是IOC。控制反转是一种设计原则,它将对象的创建和管理从对象本身剥离出来...

    spring中的BeanFactory解析xml文件

    当我们谈论“Spring中的BeanFactory解析XML文件”时,我们实际上是在讨论如何通过XML配置文件来定义、创建和管理bean。这篇文章将深入探讨BeanFactory的工作原理,以及XML配置文件在其中的作用。 首先,BeanFactory...

    自定义 Schema 解析 Spring Bean

    4. **注册Schema处理器**: 将处理器注册到Spring的SchemaRegistry,这样当Spring解析XML时,就会调用相应的处理器处理自定义元素。 通过以上步骤,我们成功地扩展了Spring的XML配置,使得项目团队可以根据业务需求...

    Spring 源代码解析

    Spring 源代码解析Spring 源代码解析Spring 源代码解析Spring 源代码解析Spring 源代码解析Spring 源代码解析Spring 源代码解析Spring 源代码解析Spring 源代码解析Spring 源代码解析Spring 源代码解析Spring 源代码...

    Spring源码解析.zip

    《Spring源码解析》 Spring框架作为Java领域最流行的开源框架之一,它的设计思想和实现原理一直是许多开发者深入研究的重点。本压缩包“Spring源码解析”提供了对Spring框架核心组件——IOC(Inversion of Control...

    Spring源码深度解析第二版

    Spring源码深度解析第二版 Spring是一款广泛应用于Java企业级应用程序的开源框架,旨在简化Java应用程序的开发和部署。Spring框架的核心主要包括了IoC容器、AOP、MVC框架等模块。 第1章 Spring整体架构和环境搭建 ...

    Spring源代码解析

    Spring源代码解析(一):IOC容器 Spring源代码解析(二):IoC容器在Web容器中的启动 Spring源代码解析(三):Spring JDBC Spring源代码解析(四):Spring MVC Spring源代码解析(五):Spring AOP获取Proxy Spring源...

    Spring源码解析.pdf

    ### Spring源码解析知识点 #### 一、Spring IoC 容器详解 ##### 1. BeanFactory —— 最基础的IoC容器 - **概念**:`BeanFactory` 是Spring框架中最基本的IoC容器,它负责管理Bean的生命周期,包括创建、配置和...

    Spring技术内幕:深入解析Spring架构与设计原理

    《Spring技术内幕:深入解析Spring架构与设计原理(第2版)》从源代码的角度对Spring的内核和各个主要功能模块的架构、设计和实现原理进行了深入剖析。你不仅能从本书中参透Spring框架的出色架构和设计思想,还能从...

    Spring三大URL路径解析器(附工程源代码)

    在Spring框架中,URL路径解析是构建Web应用的关键部分,它允许我们定义优雅的路由规则并将请求映射到相应的处理方法。本篇文章将深入探讨Spring中的三种主要URL路径解析器,包括`SimpleUrlHandlerMapping`、`...

    Spring源代码解析.rar

    Spring源代码解析1:IOC容器.doc Spring源代码解析2:IoC容器在Web容器中的启动.doc Spring源代码解析3:Spring JDBC .doc Spring源代码解析4:Spring MVC .doc Spring源代码解析5:Spring AOP获取Proxy .doc Spring...

    Spring技术内幕:深入解析Spring架构与设计原理[汇编].pdf

    Spring技术内幕:深入解析Spring架构与设计原理 Spring是Java企业应用开发的主要框架之一,其架构和设计原理对Java开发者具有重要影响。本文将深入解析Spring架构和设计原理,对Spring的核心概念、架构设计和关键...

Global site tag (gtag.js) - Google Analytics