Spring学习笔记(转载)

Spring学习笔记(1)----简单的实例
---------------------------------
 
首先需要准备Spring包,可从官方网站上下载。
 
下载解压后,必须的两个包是spring.jar和commons-logging.jar。此外为了便于测试加入了JUnit包。
 
在Myeclipse中创建Java项目。
 
编写一个接口类,为了简单,只加入了一个方法。
 
Java代码  
1.package com.szy.spring.interfacebean;  
2.  
3.public interface PersonBean  
4.{  
5.    void show();  
6.}  
  
然后写一个类实现这个接口。
  
 
 
Java代码  
1.package com.szy.spring.implbean;  
2.import com.szy.spring.interfacebean.PersonBean;  
3.  
4.public class UserBean implements PersonBean  
5.{  
6.  
7.    public void show()  
8.    {  
9.        System.out.println("Hello Kuka");  
10.    }  
11.  
12.}  
  
  
  
  
  
以上的过程我们再熟悉不过了,下面开始加入Spring的内容了。首先从下载的Sping包中找到配置文件,删除不需要的,找到最原始的部分:
  
 
 
Xml代码  
1.<?xml version="1.0" encoding="UTF-8"?>  
2.<beans xmlns="http://www.springframework.org/schema/beans" 
3.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
4.    xmlns:context="http://www.springframework.org/schema/context" 
5.    xmlns:tx="http://www.springframework.org/schema/tx" 
6.    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
7.                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  
8.                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
9.  
10.</beans>  
  
  
  
我们在配置文件中加入我们的bean信息
  
 
 
Xml代码  
1.<bean id="userBean" class="com.szy.spring.implbean.UserBean" />  
  
其中id作为标识符,class为类的包路径。
  
这样我们的配置文件就写好了,完整的配置文件呢如下。
  
 
 
Xml代码  
1.<?xml version="1.0" encoding="UTF-8"?>  
2.<beans xmlns="http://www.springframework.org/schema/beans" 
3.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
4.    xmlns:context="http://www.springframework.org/schema/context" 
5.    xmlns:tx="http://www.springframework.org/schema/tx" 
6.    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
7.                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  
8.                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
9.  
10.    <bean id="userBean" class="com.szy.spring.implbean.UserBean" />  
11.</beans>  
  
  
  
  
  
最后我们创建一个测试类测试:
  
 
 
Java代码  
1.package com.szy.spring.test;  
2.  
3.import org.junit.Test;  
4.import org.springframework.context.ApplicationContext;  
5.import org.springframework.context.support.ClassPathXmlApplicationContext;  
6.import com.szy.spring.interfacebean.PersonBean;  
7.  
8.  
9.public class TestClass  
10.{  
11.    @Test 
12.    public void testMethod() throws Exception  
13.    {  
14.        //读取配置文件  
15.        ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");  
16.        //获取UserBean的实例  
17.        PersonBean bean=(PersonBean)ctx.getBean("userBean");  
18.        //调用方法  
19.        bean.show();  
20.    }  
21.}  
 
运行,输入如下结果:
  
 
结果代码  
1.Hello Kuka  
 
Ok,我们的第一个Spring程序成功运行。
 
 
 
Sping学习笔记(2)----实例化Bean的三种方式
-------------------------------------------
Spring的实例化Bean有三种方式:
  
使用类构造器直接实例化
  
使用静态工厂的方法实例化
  
使用实例工厂方法实例化
  
  
  
三种方式对应的配置如下
  
 
 
Xml代码  
1.<?xml version="1.0" encoding="UTF-8"?>  
2.<beans xmlns="http://www.springframework.org/schema/beans" 
3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
4.        xmlns:context="http://www.springframework.org/schema/context" 
5.        xmlns:tx="http://www.springframework.org/schema/tx" 
6.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
7.                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  
8.                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
9.        <!-- 使用类构造器直接实例化 -->    
10.        <bean id="userBean1" class="com.szy.spring.implbean.UserBean" />  
11.        <!-- 使用静态工厂的方法实例化 -->  
12.        <bean id="userBean2" class="com.szy.spring.factory.BeanFactory" factory-method="UserBeanService" />  
13.        <!-- 使用实例工厂方法实例化 -->  
14.        <bean id="factory" class="com.szy.spring.factory.BeanFactory" />  
15.        <bean id="userBean3" factory-bean="factory" factory-method="getUserBeanService" />  
16.</beans>  
  
  
  
  
  
其中BeanFactory类的代码如下
  
 
 
Java代码  
1.package com.szy.spring.factory;  
2.  
3.import com.szy.spring.implbean.UserBean;  
4.import com.szy.spring.interfacebean.PersonBean;  
5.  
6.public class BeanFactory  
7.{  
8.    //使用静态工厂的方法实例化使用  
9.    public static PersonBean UserBeanService()  
10.    {  
11.        return new UserBean();  
12.    }  
13.      
14.    public PersonBean getUserBeanService()  
15.    {  
16.        return new UserBean();  
17.    }  
18.}  
  
  
  
在这三种方式中我们最常用的还是第一种。
 
 
 
 
 
 
 
Spring学习笔记(3)----编码剖析Spring管理Bean的原理
--------------------------------------------------
 
 
Xml代码  
1.<?xml version="1.0" encoding="UTF-8"?>  
2.<beans xmlns="http://www.springframework.org/schema/beans" 
3.        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
4.        xmlns:context="http://www.springframework.org/schema/context" 
5.        xmlns:tx="http://www.springframework.org/schema/tx" 
6.        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
7.                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  
8.                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
9.        <bean id="userBean" class="com.szy.spring.implbean.UserBean" />  
10.</beans>  
  
  
  
Spring的配置文件中记录了类的包路径,因此我们首先是要读入配置文件。在配置文件中Bean有id和class两个属性,我们首先定义一个Bean类,包含这两个属性:
  
  
  
 
 
Java代码  
1.package com.szy.spring.implbean;  
2.  
3.public class Bean  
4.{  
5.    private String id;  
6.    private String className;  
7.    public String getId()  
8.    {  
9.        return id;  
10.    }  
11.    public void setId(String id)  
12.    {  
13.        this.id = id;  
14.    }  
15.    public String getClassName()  
16.    {  
17.        return className;  
18.    }  
19.    public void setClassName(String className)  
20.    {  
21.        this.className = className;  
22.    }  
23.      
24.}  
25.   
  
由于配置文件是xml文件,在这里使用Jdom包操作xml文件,读入配置文件中的Bean信息。
  
 
 
Java代码  
1./** 
2.     * 读取xml配置文件 
3.     * @param fileName 配置文件名 
4.     */ 
5.    private void readXML(String fileName)  
6.    {  
7.        // 寻找配置文件  
8.        URL xmlPath = this.getClass().getClassLoader().getResource(fileName);  
9.        Document doc = null;  
10.        Element root = null;  
11.        try 
12.        {  
13.            SAXBuilder sb = new SAXBuilder(false);  
14.            doc = sb.build(new FileInputStream(new File(xmlPath.toURI())));  
15.            // 设置命名空间  
16.            Namespace xhtml = Namespace.getNamespace("xhtml",  
17.                    "http://www.springframework.org/schema/beans");  
18.            root = doc.getRootElement(); // 获取根元素  
19.            List<Element> list = root.getChildren("bean", xhtml); //获取全部bean节点  
20.            for (Element element : list)// 遍历节点,取得每个节点的属性  
21.            {  
22.                String id = element.getAttributeValue("id");  
23.                String className = element.getAttributeValue("class");  
24.                Bean bean = new Bean();  
25.                bean.setId(id);  
26.                bean.setClassName(className);  
27.                beanList.add(bean);  
28.            }  
29.        } catch (Exception e)  
30.        {  
31.            e.printStackTrace();  
32.        }  
33.  
34.    }  
  
  
  
其中beanList是一个List对象,因为在配置文件中存在很多Bean。
  
  
  
得到了所有的Bean对象后,下面就实例化每个Bean对象,结果存放在Map对象中。
  
  
  
 
 
Java代码  
1./** 
2.     * bean的实例化 
3.     */ 
4.    private void instanceBeans()  
5.    {  
6.        for (Bean bean : beanList)  
7.        {  
8.            try 
9.            {  
10.                if (bean.getClassName() != null && !"".equals(bean.getClassName().trim()))  
11.                    beanObject.put(bean.getId(), Class.forName(bean.getClassName()).newInstance());  
12.            } catch (Exception e)  
13.            {  
14.                e.printStackTrace();  
15.            }  
16.        }  
17.  
18.    }  
  
其中beanObject为Map对象。
  
  
  
最后再加入一个方法,方便外部能获取Map中的对象
  
 
 
Java代码  
1./** 
2.     * 获取bean实例 
3.     * @param beanName 配置文件中bean的Id 
4.     * @return 
5.     */ 
6.    public Object getBean(String beanName)  
7.    {  
8.        return this.beanObject.get(beanName);  
9.    }  
  
完整的MyClassPathXMLApplicationContext见附件中的代码。
  
  
  
下面测试MyClassPathXMLApplicationContext类。
  
 
 
Java代码  
1.@Test 
2.    public void testMethod() throws Exception  
3.    {  
4.        //读取配置文件  
5.        MyClassPathXMLApplicationContext ctx=new MyClassPathXMLApplicationContext("applicationContext.xml");  
6.        //获取UserBean的实例  
7.        PersonBean bean=(PersonBean)ctx.getBean("userBean");  
8.        //调用方法  
9.        bean.show();  
10.    }  
  
  
  
输出结果
  
 
 
结果代码  
1.Hello Kuka  
  
  
  
成功。
  
上面仅是简单的演示了Spring管理Bean的原理,但是在实际操作中还需要考虑很对其它因素。
 
 
 
 
 
 
 
 
Spring学习笔记(4)----Bean节点信息配置
---------------------------------------
默认情况下,Spring的Ioc容器启动时会初始化bean,但是我们可以指定Bean节点的lazy-init="true",来延迟初始化bean。这时候,只有第一次获取bean才会初始化bean。如
  
 
 
Xml代码  
1.<bean id="userBean" class="com.szy.spring.implbean.UserBean" lazy-init="true" />  
  
如果想对所有的bean有应用延迟初始化,可以在跟节点beans设置default-lazy-init="true",如下:
  
 
 
Xml代码  
1.<beans default-lazy-init="true"....>  
  
此外,如果我们还想UserBean在实例化是调用初始化方法时,我们可以加入“init-method="init"”属性,其中init为Userbean中的init()方法,与之对应,“destroy-method="destroy"”为销毁属性。
  
在Spring中我们通过getBean(name)方法获得实例,那么我们每次获取的实例化对象是一个还是多个呢?
  
我们可以通过“==”进行测试
  
 
 
Java代码  
1.ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");     
2.PersonBean bean1=(PersonBean)ctx.getBean("userBean");  
3.PersonBean bean2=(PersonBean)ctx.getBean("userBean");  
4.System.out.println(bean1==bean2);  
  
运行输出结果为:true
  
这说明了Bean交给sping容器管理之后,Bean默认情况下是单实例的。
  
如果我们想每次通过getBean(name)方法获得实例是一个新的实例化对象该怎么办呢?
  
在配置文件中节点bean有一个属性scope,只要我们配置如下即可:
  
 
 
Xml代码  
1.<bean id="userBean" class="com.szy.spring.implbean.UserBean" scope="prototype" />  
  
在运行测试代码,输出结果为:false
 
 
 
Spring学习笔记(5)----依赖注入的简单实现
-----------------------------------------
Spring的核心机制是依赖注入。依赖注入让bean与bean之间以配置文件组织在一起,而不是以硬编码的方式耦合在一起。依赖注入(Dependency Injection)和控制反转(Inversion of Control)是同一个概念。具体含义是:当某个角色(可能是一个Java实例,调用者)需要另一个角色(另一个Java实例,被调用者)的协助时,在传统的程序设计过程中,通常由调用者来创建被调用者的实例。但在Spring里,创建被调用者的工作不再由调用者来完成,因此称为控制反转;创建被调用者实例的工作通常由Spring容器来完成,然后注入调用者,因此也称为依赖注入。管是依赖注入,还是控制反转,都说明Spring采用动态、灵活的方式来管理各种对象。对象与对象之间的具体实现互相透明。
  
下面通过简单的实例演示依赖注入。
  
项目中主要包含一下一个文件:
 
  
  
UserDAO是一个接口,包含了一个方法:
  
 
 
Java代码  
1.package com.szy.spring.dao;  
2.  
3.public interface UserDAO  
4.{  
5.    void show();  
6.}  
  
  
  
而UserDAO4MySqlImpl和UserDAO4OracleImpl实现了UserDAO中的方法。
  
 
 
Java代码  
1.package com.szy.spring.dao;  
2.public class UserDAO4MySqlImpl implements UserDAO  
3.{  
4.    public void show()  
5.    {  
6.        System.out.println("MySqlDAO Implement");  
7.    }  
8.}  
  
  
  
 
 
Java代码  
1.package com.szy.spring.dao;  
2.public class UserDAO4OracleImpl implements UserDAO  
3.{  
4.    public void show()  
5.    {  
6.        System.out.println("OracleDAO Implement");  
7.    }  
8.}  
  
  
  
UserService是另外一个包中的接口,
  
 
 
Java代码  
1.package com.szy.spring.service;  
2.  
3.public interface UserService  
4.{  
5.    void show();  
6.}  
  
  
  
UserServiceImpl实现了这个接口,
  
 
 
Java代码  
1.package com.szy.spring.service;  
2.  
3.import com.szy.spring.dao.UserDAO;  
4.  
5.public class UserServiceImpl implements UserService  
6.{  
7.    private UserDAO userDAO;  
8.      
9.    public void show()  
10.    {  
11.        userDAO.show();  
12.    }  
13.  
14.    public UserDAO getUserDAO()  
15.    {  
16.        return userDAO;  
17.    }  
18.    public void setUserDAO(UserDAO userDAO)  
19.    {  
20.        this.userDAO = userDAO;  
21.    }  
22.}  
  
但是在实现这个接口中,调用了UserDAO中的方法。一般情况下我们需要在这里实例化一个UserDAO对象,比如
  
 
 
Java代码  
1.UserDAO userDAO=new UserDAO4MySqlImpl();  
  
这样的话耦合度就比较高,通过spring我们可以降低耦合度。
  
在Sping的配置文件中,我们需要这样配置
  
 
 
Java代码  
1.<?xml version="1.0" encoding="UTF-8"?>  
2.<beans xmlns="http://www.springframework.org/schema/beans" 
3.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
4.    xmlns:context="http://www.springframework.org/schema/context" 
5.    xmlns:tx="http://www.springframework.org/schema/tx" 
6.    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
7.                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  
8.                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
9.    <bean id="mySqlDAO" class="com.szy.spring.dao.UserDAO4MySqlImpl"/>  
10.    <bean id="oracleDAO" class="com.szy.spring.dao.UserDAO4OracleImpl"/>  
11.    <bean id="userService" class="com.szy.spring.service.UserServiceImpl">  
12.        <!--构造方法注入    
13.            <property name="userDAO" ref="mySqlDAO"></property>  
14.        -->  
15.        <property name="userDAO" ref="oracleDAO"></property>  
16.    </bean>  
17.</beans>  
  
  
  
下面我们测试
  
 
 
Java代码  
1.ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");     
2.        UserService service=(UserService)ctx.getBean("userService");  
3.        service.show();  
  
  
  
输入内容为
  
 
 
输出代码  
1.OracleDAO Implement  
  
如果我们想实用Mysql数据库呢? 
  
此时我们只要修改配置文件即可,而不需要修改Java文件。
  
 
 
Xml代码  
1.<property name="userDAO" ref="mySqlDAO"></property>  
 
 
 
 
 
 
 
 
Spring学习笔记(6)----编码剖析Spring依赖注入的原理
---------------------------------------------------
在Spring学习笔记(3)中剖析了Spring管理Bean的原理,下面解释下Spring依赖注入的原理
  
在进行依赖注入时,我们的配置文件如下配置:
  
 
 
Xml代码  
1.<?xml version="1.0" encoding="UTF-8"?>  
2.<beans xmlns="http://www.springframework.org/schema/beans" 
3.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
4.    xmlns:context="http://www.springframework.org/schema/context" 
5.    xmlns:tx="http://www.springframework.org/schema/tx" 
6.    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
7.                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  
8.                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
9.    <bean id="mySqlDAO" class="com.szy.spring.dao.UserDAO4MySqlImpl"/>  
10.    <bean id="oracleDAO" class="com.szy.spring.dao.UserDAO4OracleImpl"/>  
11.    <bean id="userService" class="com.szy.spring.service.UserServiceImpl">  
12.        <!--构造方法注入    
13.            <property name="userDAO" ref="mySqlDAO"></property>  
14.        -->  
15.        <property name="userDAO" ref="oracleDAO"></property>  
16.    </bean>  
17.</beans>  
  
根据配置文件信息,我们首先需要建立一个Bean类,用来保存bean节点的信息:
  
 
 
Java代码  
1.package com.szy.spring.bean;  
2.  
3.import java.util.List;  
4.  
5.public class Bean  
6.{  
7.    private String id;     
8.    private String className;   
9.    private List<Property> propertyList;  
10.    public Bean(String id, String className, List<Property> propertyList)  
11.    {  
12.        super();  
13.        this.id = id;  
14.        this.className = className;  
15.        this.propertyList = propertyList;  
16.    }  
17.    public String getId()     
18.    {     
19.        return id;     
20.    }     
21.    public void setId(String id)     
22.    {     
23.        this.id = id;     
24.    }     
25.    public String getClassName()     
26.    {     
27.        return className;     
28.    }     
29.    public void setClassName(String className)     
30.    {     
31.        this.className = className;     
32.    }  
33.    public List<Property> getPropertyList()  
34.    {  
35.        return propertyList;  
36.    }  
37.    public void setPropertyList(List<Property> propertyList)  
38.    {  
39.        this.propertyList = propertyList;  
40.    }     
41.}  
  
此外,由于bean下存在property信息,因此我们还需要建立property类
  
 
 
Java代码  
1.package com.szy.spring.bean;  
2.  
3.public class Property  
4.{  
5.    private String name;  
6.    private String ref;  
7.      
8.    public Property(String name, String ref)  
9.    {  
10.        super();  
11.        this.name = name;  
12.        this.ref = ref;  
13.    }  
14.    public String getName()  
15.    {  
16.        return name;  
17.    }  
18.    public void setName(String name)  
19.    {  
20.        this.name = name;  
21.    }  
22.    public String getRef()  
23.    {  
24.        return ref;  
25.    }  
26.    public void setRef(String ref)  
27.    {  
28.        this.ref = ref;  
29.    }  
30.      
31.}  
  
  
  
在Spring学习笔记(3)中,我们在读取xml文件时bean节点下面是不存在property节点的,因此在这里我们需要修改readXML()方法:
  
 
 
Java代码  
1./** 
2.     * 读取xml配置文件 
3.     * @param fileName 配置文件名 
4.     */ 
5.    private void readXML(String fileName)  
6.    {  
7.        // 寻找配置文件  
8.        URL xmlPath = this.getClass().getClassLoader().getResource(fileName);  
9.        Document doc = null;  
10.        Element root = null;  
11.        try 
12.        {  
13.            SAXBuilder sb = new SAXBuilder(false);  
14.            doc = sb.build(new FileInputStream(new File(xmlPath.toURI())));  
15.            // 设置命名空间     
16.            Namespace xhtml = Namespace.getNamespace("xhtml",  
17.                    "http://www.springframework.org/schema/beans");  
18.            root = doc.getRootElement(); // 获取根元素     
19.            List<Element> bList = root.getChildren("bean", xhtml); //获取全部bean节点     
20.            for (Element beanElement : bList)// 遍历节点,取得每个节点的属性     
21.            {  
22.                String id = beanElement.getAttributeValue("id");  
23.                String className = beanElement.getAttributeValue("class");  
24.                //获得每个bean下面的属性  
25.                List<Element> pList = beanElement  
26.                        .getChildren("property", xhtml);  
27.                List<Property> propertyList = new ArrayList<Property>(); //存储属性信息  
28.                if (pList.size() > 0) //如果存在属性  
29.                {  
30.                    for (Element propertyElement : pList) //遍历属性节点  
31.                    {  
32.                        String name = propertyElement.getAttributeValue("name");  
33.                        String ref = propertyElement.getAttributeValue("ref");  
34.                        Property property = new Property(name, ref);  
35.                        propertyList.add(property); //保存属性节点  
36.                    }  
37.                }  
38.                Bean bean = new Bean(id, className, propertyList);  
39.                beanList.add(bean);  
40.            }  
41.  
42.        } catch (Exception e)  
43.        {  
44.            e.printStackTrace();  
45.        }  
46.    }  
  
读取完配置文件后我们还是需要对bean进行实例化的,这方法和Spring学习笔记(3)中的instanceBeans()方法一样。下面就是我们需要给bean属性进行注入,实现方法如下:
  
 
 
Java代码  
1./** 
2.     * 为bean对象的属性注入值 
3.     */ 
4.    public void injectObject()  
5.    {  
6.        for (Bean bean : beanList)  
7.        {  
8.            Object object = beanObject.get(bean.getId()); //获取bean的实例  
9.            if (object != null)  
10.            {  
11.                try 
12.                {  
13.                    PropertyDescriptor[] ps = Introspector.getBeanInfo(  
14.                            object.getClass()).getPropertyDescriptors();  //取得bean的属性描述  
15.                    for (Property property : bean.getPropertyList())  //获取bean节点的属性  
16.                    {  
17.                        for (PropertyDescriptor properdesc : ps)    
18.                        {  
19.                            if (property.getName().equals(properdesc.getName()))  
20.                            {  
21.                                Method setter = properdesc.getWriteMethod();//获取属性的setter方法 ,private  
22.                                if (setter != null)  
23.                                {  
24.                                    Object value = beanObject.get(property.getRef());  //取得值  
25.                                    setter.setAccessible(true);  //设置为允许访问  
26.                                    setter.invoke(object, value);//把引用对象注入到属性  
27.                                }  
28.                                break;  
29.                            }  
30.                        }  
31.                    }  
32.                } catch (Exception e)  
33.                {  
34.                    e.printStackTrace();  
35.                }  
36.            }  
37.        }  
  
  
  
我们进行测试:
  
 
 
Java代码  
1.MyClassPathXMLApplicationContext ctx=new MyClassPathXMLApplicationContext("applicationContext.xml");     
2.        UserService service=(UserService)ctx.getBean("userService");  
3.        service.show();  
  
  
  
运行输出
  
 
 
结果代码  
1.OracleDAO Implement  
  
上面仅是简单的演示了Spring依赖注入的原理,但是Spring学习笔记(7)----装配各种集合类型的属性在实际操作中还需要考虑很对其它因素,在此就不进行讨论了。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
Spring学习笔记(7)----装配各种集合类型的属性
---------------------------------------------
前面已经介绍了如何给属性注入对象,下面介绍一下如何装配集合类型的属性 
1.Set类型
  
 
 
Java代码  
1.private Set<String> sets=new HashSet<String>();  
2.//我们需要给它添加set方法  
3.public Set<String> getSets()  
4.    {  
5.        return sets;  
6.    }  
7.    public void setSets(Set<String> sets)  
8.    {  
9.        this.sets = sets;  
10.    }  
11.public Set<String> showSet()  
12.    {  
13.        return sets;  
14.    }  
  
然后根据属性修改配置文件
  
 
 
Xml代码  
1.<bean id="userService" class="com.szy.spring.service.UserServiceImpl">  
2.        <property name="sets">  
3.            <set>  
4.                <value>Set1</value>  
5.                <value>Set2</value>  
6.                <value>Set3</value>  
7.            </set>      
8.        </property>  
9.  
10.</bean>  
  
与以前不同的是我们在property下面添加了<set></set>
  
这样就能装配set类型的属性
  
2.List类型
  
List类型的属性和Set类型的方法一样,主要是把配置文件中的set修改成list。
  
 
 
Java代码  
1.private List<String> lists=new ArrayList<String>();  
2.public List<String> getLists()  
3.    {  
4.        return lists;  
5.    }  
6.    public void setLists(List<String> lists)  
7.    {  
8.        this.lists = lists;  
9.    }  
10.public List<String> showList()  
11.    {  
12.        return lists;  
13.    }  
  
配置文件修改如下
  
 
 
Xml代码  
1.<bean id="userService"  class="com.szy.spring.service.UserServiceImpl">  
2.<property name="lists">  
3.            <list>  
4.                <value>List1</value>  
5.                <value>List2</value>  
6.                <value>List3</value>  
7.            </list>  
8.        </property>  
9.    </bean>  
  
3.Properties类型
  
 
 
Java代码  
1.private Properties properties=new Properties();  
2.public void setProperties(Properties properties)  
3.    {  
4.        this.properties = properties;  
5.    }  
6.public Properties getProperties()  
7.    {  
8.        return properties;  
9.    }  
10.public Properties showProperties()  
11.    {  
12.        return properties;  
13.    }  
  
配置文件需要如下配置
  
 
 
Xml代码  
1.<bean id="userService" class="com.szy.spring.service.UserServiceImpl">  
2.<property name="properties">  
3.            <props>  
4.                <prop key="key1">Properties1</prop>  
5.                <prop key="key2">Properties2</prop>  
6.                <prop key="key3">Properties3</prop>  
7.            </props>  
8.        </property>  
9.    </bean>  
10.      
  
4.Map类型
  
 
 
Java代码  
1.private Map<String, String> maps=new HashMap<String, String>();  
2.public List<String> getLists()  
3.    {  
4.        return lists;  
5.    }  
6.    public void setLists(List<String> lists)  
7.    {  
8.        this.lists = lists;  
9.    }  
10.public Map<String, String> showMaps()  
11.    {  
12.        return maps;  
13.    }  
  
配置文件做相应的配置
  
 
 
Xml代码  
1.<bean id="userService" class="com.szy.spring.service.UserServiceImpl">  
2.lt;property name="maps">  
3.        <map>  
4.            <entry key="key1" value="Map1"></entry>  
5.            <entry key="key2" value="Map2"></entry>  
6.            <entry key="key3" value="Map3"></entry>  
7.        </map>  
8.    </property>  
9.</bean>  
  
  
  
这样就完成了对Map类型的属性进行装配。
 
 
 
 
 
 
 
 
Spring学习笔记(8)----属性注入的方式
--------------------------------------
Spring中属性注入的方式有三种:
  
1.使用属性setter方法注入
  
2.使用构造器注入
  
3.使用注解方式注入
  
  
  
使用属性setter方法注入
  
使用属性setter方法注入就是给属性添加set()方法,在前面都是使用这种方法。
  
 
 
Java代码  
1.package com.szy.spring.service;  
2.  
3.import com.szy.spring.dao.PersonDao;  
4.  
5.public class UserServiceImplBySetter implements UserService  
6.{  
7.    private PersonDao personDao;  
8.      
9.    public void show()  
10.    {  
11.        personDao.show();  
12.    }  
13.    public PersonDao getPersonDao()  
14.    {  
15.        return personDao;  
16.    }  
17.    public void setPersonDao(PersonDao personDao)  
18.    {  
19.        this.personDao = personDao;  
20.    }  
21.}  
  
  
  
然后在配置文件中如下配置
  
 
 
Xml代码  
1.<bean id="personDao" class="com.szy.spring.dao.PersonDaoBean"/>  
2.    <!-- 使用属性Setter方法注入配置 -->  
3.    <bean id="userService1" class="com.szy.spring.service.UserServiceImplBySetter">  
4.        <property name="personDao" ref="personDao"></property>  
5.    </bean>  
  
  
  
使用构造器注入
  
使用构造器注入就是在类中添加含参构造函数
  
 
 
Java代码  
1.package com.szy.spring.service;  
2.  
3.import com.szy.spring.dao.PersonDao;  
4.  
5.public class UserServiceImplConstructor implements UserService  
6.{  
7.    private PersonDao personDao;  
8.    private String name;  
9.      
10.    public UserServiceImplConstructor()  
11.    {  
12.    }  
13.  
14.    public UserServiceImplConstructor(PersonDao personDao, String name)  
15.    {  
16.        this.personDao = personDao;  
17.        this.name = name;  
18.    }  
19.  
20.    public void show()  
21.    {  
22.        personDao.show();  
23.        System.out.println("name属性:"+name);  
24.    }  
25.}  
  
  
  
下面就是在配置文件中添加配置信息,给每个参数注入值
  
 
 
Xml代码  
1.<bean id="personDao" class="com.szy.spring.dao.PersonDaoBean"/>  
2.    <!-- 使用构造器参数方法注入配置 -->  
3.    <bean id="userService2" class="com.szy.spring.service.UserServiceImplConstructor">  
4.        <constructor-arg index="0" type="com.szy.spring.dao.PersonDao" ref="personDao"/>  
5.        <constructor-arg index="1" value="Kuka"/>  
6.    </bean>  
  
注意:constructor-arg index是从0开始的
  
  
  
使用注解方式注入
  
如果使用前面的两种方法,配置文件将会显得很臃肿,因此我们可以使用注解的方式注入,使用注解方式注入有两种方法,第一种使用javax.annotation.Resource中提供的注解方式方法如下:
  
 
 
Java代码  
1.package com.szy.spring.service;  
2.  
3.import javax.annotation.Resource;  
4.  
5.import com.szy.spring.dao.PersonDao;  
6.  
7.public class UserServiceImplByAnnotation4Resource implements UserService  
8.{  
9.    //@Resource默认是按照名称装配,找不到与名称匹配的bean时按类型装配  
10.    @Resource(name="personDao")private PersonDao personDao;  
11.  
12.    public void show()  
13.    {  
14.        personDao.show();  
15.    }  
16.//  下面方法同样可以  
17.//  @Resource  
18.//  public void setPersonDao(PersonDao personDao)  
19.//  {  
20.//      this.personDao = personDao;  
21.//  }  
22.      
23.}  
  
  
  
此时配置文件要做相应的改变
  
 
 
Xml代码  
1.<?xml version="1.0" encoding="UTF-8"?>  
2.<beans xmlns="http://www.springframework.org/schema/beans" 
3.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
4.    xmlns:context="http://www.springframework.org/schema/context" 
5.    xmlns:tx="http://www.springframework.org/schema/tx" 
6.    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
7.                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd  
8.                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd">  
9.    <context:annotation-config/>  
10.    <bean id="personDao" class="com.szy.spring.dao.PersonDaoBean"/>  
11.    <bean id="userService" class="com.szy.spring.service.UserServiceImplByAnnotation4Autowired">  
12.    </bean>  
13.</beans>  
  
  
  
注意添加这句配置信息
  
<context:annotation-config/>
 
  
第二中方式就是使用spring提供的注解方式
  
org.springframework.beans.factory.annotation.Autowired;
  
注入使用时需要导入spring目录lib\j2ee\common-annotations.jar这个包
  
使用方法如下:
  
 
 
Java代码  
1.package com.szy.spring.service;  
2.  
3.import org.springframework.beans.factory.annotation.Autowired;  
4.import org.springframework.beans.factory.annotation.Qualifier;  
5.  
6.import com.szy.spring.dao.PersonDao;  
7.  
8.public class UserServiceImplByAnnotation4Autowired implements UserService  
9.{  
10.    //@Autowired默认使用类型进行装配,  
11.    @Autowired private PersonDao personDao;  
12.//  如果使用按名称进行装配,则需要如下  
13.//  @Autowired @Qualifier("personDao")private PersonDao personDao;  
14.    public void show()  
15.    {  
16.        personDao.show();  
17.    }  
18.      
19.}  
  
  
  
配置文件和上面一样。
  
  
  
在使用时建议使用@Resource,因为@Resource不依赖于spring框架。
 
 
 
 
 
 
Spring学习笔记(9)----让Spring自动扫描和管理Bean
-------------------------------------------------
 
 
 
Java代码  
1.package com.szy.spring.service;  
2.  
3.import org.springframework.stereotype.Service;  
4.  
5.import com.szy.spring.dao.PersonDao;  
6.@Service("service")  
7.public class UserServiceImpl implements UserService  
8.{  
9.    private PersonDao personDaoBean;  
10.      
11.    public void show()  
12.    {  
13.        personDaoBean.show();  
14.    }  
15.  
16.    public void setPersonDaoBean(PersonDao personDaoBean)  
17.    {  
18.        this.personDaoBean = personDaoBean;  
19.    }  
20.}  
  
在前面的例子中,都是使用XML的bean定义来使用组件,在大的项目中,通常会有上百个组件,如果这些组件采用xml的bean定义来配置,显然会使配置文件显得很臃肿,查找和维护起来不方便。Spring2.5为我们引入了组件自动扫描机制,它可以在类路径下寻找标记了@Component、@Service、@Controller、@Repository注解的类,并把这些类纳入到spring容器中管理,它的作用和在xml中使用bean节点配置组件一样。要使用自动扫描机制,我们需要把配置文件如下配置:
  
 
 
Xml代码  
1.<?xml version="1.0" encoding="UTF-8"?>  
2.<beans xmlns="http://www.springframework.org/schema/beans" 
3.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
4.    xmlns:context="http://www.springframework.org/schema/context" 
5.    xmlns:tx="http://www.springframework.org/schema/tx" 
6.    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
7.                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  
8.                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
9.    <context:component-scan base-package="com.szy.spring"></context:component-scan>  
10.</beans>  
  
其中base-package为需要扫描的包(包括子包)
  
@Service用于标注业务层的组件,@Controller用于标注控制层组件(如struts中的action),@Repository用于标注数据访问组件,即DAO组件,而@Component泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注。但是在目前的spring版本中,这几个注解的作用是一样的,但是在以后可能会进行区分。
  
  
  
下面把先前的例子修改一下:
  
首先是PersonDaoBean类,修改如下
  
 
 
Java代码  
1.package com.szy.spring.dao;  
2.  
3.import org.springframework.stereotype.Repository;  
4.  
5.@Repository 
6.//告诉spring这个类要交给spring管理,  
7.public class PersonDaoBean implements PersonDao  
8.{  
9.    public void show()  
10.    {  
11.        System.out.println("执行PersonDaoBean中的add()方法");  
12.    }  
13.}  
  
  
  
然后是UserServiceImpl类
  
 
 
Java代码  
1.package com.szy.spring.service;  
2.  
3.import org.springframework.stereotype.Service;  
4.  
5.import com.szy.spring.dao.PersonDao;  
6.@Service 
7.//把这个类交给spring管理,作为服务了。  
8.public class UserServiceImpl implements UserService  
9.{  
10.    private PersonDao personDaoBean;  
11.      
12.    public void show()  
13.    {  
14.        personDaoBean.show();  
15.    }  
16.  
17.    public void setPersonDaoBean(PersonDao personDaoBean)  
18.    {  
19.        this.personDaoBean = personDaoBean;  
20.    }  
21.  
22.    public PersonDao getPersonDaoBean()  
23.    {  
24.        return personDaoBean;  
25.    }  
26.}  
  
  
  
  
  
下面我们进行测试,原来的测试代码是userServiceImpl 
 
 
 
Java代码  
1.ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");  
2.        UserService service=(UserService)ctx.getBean("userService");  
3.        service.show();  
  
  
  
其中userService是我们在配置文件中配置的bean的id。但是如今我们并没有id这个属性,在spring2.5中,默认的id是类的名称,但是开后是小写,也就是userServiceImpl,因此测试代码应修改如下:
  
 
 
Java代码  
1.AbstractApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");  
2.        UserService service=(UserService)ctx.getBean("userServiceImpl");  
3.        System.out.println(service);  
  
  
  
如果我们想自己命名的话,则只需在注解后加上括号,里面写入你希望的名字,如
  
@Service("userService")。
  
  
  
在spring中默认的是之生成一个bean实例,如果我们想每次调用都产生一个实例,则标注需如下配置
  
@Service @Scope("prototype")
  
  
  
在xml中我们还可以配置初始化方法和销毁方法,使用标注后只需如下标注
  
 
 
Java代码  
1.@PostConstruct 
2.    public void init()  
3.    {  
4.        System.out.println("初始化");  
5.    }  
6.    @PreDestroy 
7.    public void destory()  
8.    {  
9.        System.out.println("销毁");  
10.    }  
  
  
  
使用注解后,我们的xml文件变得十分简单,因此建议Spring学习笔记(10)----公共属性的注入配置大家在以后的开发中使用注解。
 
 
 
 
 
 
 
 
 
 
Spring学习笔记(10)----公共属性的注入配置
-------------------------------------------
假设我们定义了四个bean类,其代码分别如下:
  
 
 
Java代码  
1.package com.szy.spring.bean;  
2.  
3.public class Bean1 {  
4.    private Bean2 bean2;  
5.    private Bean3 bean3;  
6.    private Bean4 bean4;  
7.  
8.    public Bean2 getBean2()  
9.    {  
10.        return bean2;  
11.    }  
12.    public void setBean2(Bean2 bean2)  
13.    {  
14.        this.bean2 = bean2;  
15.    }  
16.    public Bean3 getBean3()  
17.    {  
18.        return bean3;  
19.    }  
20.    public void setBean3(Bean3 bean3)  
21.    {  
22.        this.bean3 = bean3;  
23.    }  
24.    public Bean4 getBean4()  
25.    {  
26.        return bean4;  
27.    }  
28.    public void setBean4(Bean4 bean4)  
29.    {  
30.        this.bean4 = bean4;  
31.    }  
32.}  
  
  
  
  
  
 
 
Java代码  
1.package com.szy.spring.bean;  
2.  
3.public class Bean2  
4.{  
5.    private int id;  
6.    private String name;  
7.    private String password;  
8.  
9.    public int getId()  
10.    {  
11.        return id;  
12.    }  
13.    public void setId(int id)  
14.    {  
15.        this.id = id;  
16.    }  
17.    public String getName()  
18.    {  
19.        return name;  
20.    }  
21.    public void setName(String name)  
22.    {  
23.        this.name = name;  
24.    }  
25.    public String getPassword()  
26.    {  
27.        return password;  
28.    }  
29.    public void setPassword(String password)  
30.    {  
31.        this.password = password;  
32.    }  
33.}  
  
  
  
  
  
 
 
Java代码  
1.package com.szy.spring.bean;  
2.  
3.public class Bean3  
4.{  
5.    private int id;  
6.    private String name;  
7.  
8.    public int getId()  
9.    {  
10.        return id;  
11.    }  
12.    public void setId(int id)  
13.    {  
14.        this.id = id;  
15.    }  
16.    public String getName()  
17.    {  
18.        return name;  
19.    }  
20.    public void setName(String name)  
21.    {  
22.        this.name = name;  
23.    }  
24.}  
  
  
  
  
  
 
 
Java代码  
1.package com.szy.spring.bean;  
2.  
3.public class Bean4  
4.{  
5.    private int age;  
6.  
7.    public int getAge()  
8.    {  
9.        return age;  
10.    }  
11.    public void setAge(int age)  
12.    {  
13.        this.age = age;  
14.    }  
15.}  
  
  
  
按照正常的思路,我们下面就要给每个类进行属性的注入,配置文件如下设置:
  
 
 
Xml代码  
1.<?xml version="1.0" encoding="UTF-8"?>  
2.<beans xmlns="http://www.springframework.org/schema/beans" 
3.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
4.    xmlns:context="http://www.springframework.org/schema/context" 
5.    xmlns:tx="http://www.springframework.org/schema/tx" 
6.    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
7.                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  
8.                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
9.    <bean id="bean1" class="com.szy.spring.bean.Bean1">  
10.        <property name="bean2" ref="bean2"/>  
11.        <property name="bean3">  
12.            <ref bean="bean3"/>  
13.        </property>     
14.        <property name="bean4" ref="bean4"/>  
15.    </bean>  
16.      
17.    <bean id="bean2" class="com.szy.spring.bean.Bean2">  
18.        <property name="id" value="100"/>  
19.        <property name="name">  
20.            <value>kuka</value>  
21.        </property>  
22.        <property name="password" value="123"/>  
23.    </bean>  
24.      
25.    <bean id="bean3" class="com.szy.spring.bean.Bean3">  
26.        <property name="id" value="100"/>  
27.        <property name="name" value="kuka"/>  
28.    </bean>  
29.       
30.    <bean id="bean4" class="com.szy.spring.bean.Bean4">  
31.        <property name="age" value="22"/>  
32.    </bean>  
33.</beans>  
  
  
  
我们进行测试:
  
 
 
Java代码  
1.@Test 
2.    public void testMethod() throws Exception  
3.    {  
4.        ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");  
5.        Bean1 bean1 = (Bean1)ctx.getBean("bean1");  
6.          
7.        System.out.println("bean1.bean2.id=" + bean1.getBean2().getId());  
8.        System.out.println("bean1.bean2.name=" + bean1.getBean2().getName());  
9.        System.out.println("bean1.bean2.password=" + bean1.getBean2().getPassword());  
10.        System.out.println("bean1.bean3.id=" + bean1.getBean3().getId());  
11.        System.out.println("bean1.bean3.name=" + bean1.getBean3().getName());  
12.        System.out.println("bean1.bean4.age=" + bean1.getBean4().getAge());  
13.    }  
  
  
  
正常输出我们所预期的信息,但是我们观察发现bean2和bean3的部分属性的配置信息是相同的,这仅是两个bean,如果是多个bean的话我们要修改就好修改多处,因此我们可以把这些公共的部分提出出来,进行抽象。这个在Spring中是支持的。我们在建立一个配置文件,命名为:applicationCommon.xml,其内容如下配置
  
 
 
Xml代码  
1.<?xml version="1.0" encoding="UTF-8"?>  
2.<beans xmlns="http://www.springframework.org/schema/beans" 
3.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
4.    xmlns:context="http://www.springframework.org/schema/context" 
5.    xmlns:tx="http://www.springframework.org/schema/tx" 
6.    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
7.                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  
8.                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
9.     <bean id="beanAbstract" abstract="true">  
10.        <property name="id" value="100"/>  
11.        <property name="name" value="kuka"/>  
12.   </bean>           
13.     
14.   <bean id="bean2" class="com.szy.spring.bean.Bean2" parent="beanAbstract">  
15.            <property name="password" value="123"/>  
16.   </bean>          
17.     
18.   <bean id="bean3" class="com.szy.spring.bean.Bean3" parent="beanAbstract"/>  
19.      
20.</beans>  
  
beanAbstract就是我们抽象出来的,设置abstract="true"属性后就不需要指定class属性。
  
我们把原来配置文件里的关于bean2和bean3节点注释掉。
  
下面进行测试,在这里要注意由于我们使用了两个配置文件,因此我们在读取是要写两个配置文件名。我们查看ClassPathXmlApplicationContext源文件发现其有个构造函数参数是string数组,因此我们可以把这个配置文件名放在数组里面。此外我们还有另外一种实现方法,两个配置文件一个叫applicationContext.xml,另一个applicationCommon.xml,公共部分是applicationC*.xml,下面我们就可以这样进行测试:
  
 
 
Java代码  
1.@Test 
2.    public void testMethod() throws Exception  
3.    {  
4.        ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationC*.xml");  
5.        Bean1 bean1 = (Bean1)ctx.getBean("bean1");  
6.          
7.        System.out.println("bean1.bean2.id=" + bean1.getBean2().getId());  
8.        System.out.println("bean1.bean2.name=" + bean1.getBean2().getName());  
 
 
9.        System.out.println("bean1.bean2.password=" + bean1.getBean2().getPassword());  
10.        System.out.println("bean1.bean3.id=" + bean1.getBean3().getId());  
11.        System.out.println("bean1.bean3.name=" + bean1.getBean3().getName());  
12.        System.out.println("bean1.bean4.age=" + bean1.getBean4().getAge());  
13.    }  
  
  
  
如果我们bean2的name属性的值不是kuka,那么我们只需在applicationCommon.xml文件的bean2节点下再添加property属性即可
  
 
 
Xml代码  
1.<property name="name" value="coolszy"/>  
 
 
 
 
 
 
 
 
 
 
 
 
Spring学习笔记(11)----自定义属性编辑器
-------------------------------------------
前面我们所定义的属性都是几本的属性,如果我们定义一个属性是Date类型,例如如下类中:
  
 
 
Java代码  
1.package com.szy.spring.bean;  
2.  
3.import java.util.Date;  
4.  
5.public class Bean {  
6.    private Date date;  
7.  
8.    public Date getDate()  
9.    {  
10.        return date;  
11.    }  
12.    public void setDate(Date date)  
13.    {  
14.        this.date = date;  
15.    }  
16.}  
  
按照我们以前学过的知识我们需要在配置文件中给该属性注入值
  
 
 
Xml代码  
1.<bean id="bean" class="com.szy.spring.bean.Bean">  
2.        <property name="date" value="2009-11-21"/>  
3.    </bean>  
  
下面我们测试是否成功注入值
  
 
 
Java代码  
1.ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");  
2.        Bean bean = (Bean)ctx.getBean("bean");  
3.        System.out.println(bean.getDate());  
  
运行包如下异常
  
 
 
Exception代码  
1.org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'bean' defined in class path resource [applicationContext.xml]: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type [java.lang.String] to required type [java.util.Date] for property 'date'; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [java.lang.String] to required type [java.util.Date] for property 'date': no matching editors or conversion strategy found  
  
通过错误提示信息我们得知spring不能将string转换成date类型,没有匹配的编辑器或者转换机制。
如果想实现string转换成Date,那么我们自己需要写一个属性编辑器
  
我们新建一个类DatePropertyEditor,这个类要继承PropertyEditorSupport类。
我们需要复写这个类中的setAsText方法,其中text参数就是配置文件中的值。我们的任务就是把text转换成date类型的值。
  
 
 
Java代码  
1.package com.szy.spring.util;  
2.  
3.import java.beans.PropertyEditorSupport;  
4.import java.text.SimpleDateFormat;  
5.import java.util.Date;  
6.  
7.public class DatePropertyEditor extends PropertyEditorSupport  
8.{  
9.  
10.    @Override 
11.    public void setAsText(String text) throws IllegalArgumentException  
12.    {  
13.        String format="yyyy-MM-dd";  
14.        SimpleDateFormat sdf=new SimpleDateFormat(format);  
15.        try 
16.        {  
17.            Date date=sdf.parse(text);  
18.            this.setValue(date);  //把转换后的值传过去  
19.        } catch (Exception e)  
20.        {  
21.            e.printStackTrace();  
22.        }  
23.    }  
24.  
25.}  
  
写完编辑器后我们还需要把编辑器注入到spring中。 为了方便管理我们再新建一个配置文件applicationEditor.xml,用来配置属性编辑器
  
 
 
Xml代码  
1.<?xml version="1.0" encoding="UTF-8"?>  
2.<beans xmlns="http://www.springframework.org/schema/beans" 
3.    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
4.    xmlns:context="http://www.springframework.org/schema/context" 
5.    xmlns:tx="http://www.springframework.org/schema/tx" 
6.    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
7.                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd  
8.                http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">  
9.    <bean id="customEditorConfigurer" class="org.springframework.beans.factory.config.CustomEditorConfigurer">  
10.        <!-- 把值注入到CustomEditorConfigurer的 Map类型的customEditors属性-->  
11.        <property name="customEditors">  
12.            <map>  
13.                <entry key="java.util.Date">  
14.                    <!-- 内部bean只供自己使用 -->  
15.                    <bean class="com.szy.spring.util.DatePropertyEditor"/>  
16.                </entry>  
17.            </map>  
18.        </property>  
19.    </bean>  
20.      
21.</beans>  
  
  
  
下面我们修改下测试代码已读取所有的配置文件
  
 
 
Java代码  
1.ApplicationContext ctx=new ClassPathXmlApplicationContext("application*.xml");  
2.        Bean bean = (Bean)ctx.getBean("bean");  
3.        System.out.println(bean.getDate());  
  
  
  
最后测试,成功输出时间。
  
刚才我们在配置文件中时间的格式是2009-11-21,如果我们修改成2009/11/21呢?
  
运行报错:Unparseable date: "2009/11/21"
  
这时我们需要修改属性编辑器类文件的格式了,很麻烦。既然spring支持注入,那么我们为什么不对格式进行注入呢?
  
修改属性编辑器类:
  
 
 
Java代码  
1.package com.szy.spring.util;  
2.  
3.import java.beans.PropertyEditorSupport;  
4.import java.text.SimpleDateFormat;  
5.import java.util.Date;  
6.  
7.public class DatePropertyEditor extends PropertyEditorSupport  
8.{  
9.  
10.    private String format;  
11.    @Override 
12.    public void setAsText(String text) throws IllegalArgumentException  
13.    {  
14.          
15.        SimpleDateFormat sdf=new SimpleDateFormat(format);  
16.        try 
17.        {  
18.            Date date=sdf.parse(text);  
19.            this.setValue(date);  //把转换后的值传过去  
20.        } catch (Exception e)  
21.        {  
22.            e.printStackTrace();  
23.        }  
24.    }  
25.    public String getFormat()  
26.    {  
27.        return format;  
28.    }  
29.    public void setFormat(String format)  
30.    {  
31.        this.format = format;  
32.    }  
33.}  
  
  
  
同时给该类对应的bean添加属性节点
  
 
 
Xml代码  
1.<bean class="com.szy.spring.util.DatePropertyEditor">  
2.                        <property name="format" value="yyyy/MM/dd"></property>  
3.                    </bean>  
  
  
  
下次只要我们修改配置文件即可,灵活性很大。
 
 
 
 
 
 
 
 
Spring学习笔记(12)----静态代理模式分析演示
--------------------------------------------
代理模式分为静态代理和动态代理。静态代理就是我们自己定义的代理类,动态代理是程序在运行时生成的代理类。
  
下面演示下静态代理类。首先我们要定义一个接口:
  
 
 
Java代码  
1.package com.szy.spring;  
2.  
3.public interface UserManager  
4.{  
5.    public void addUser(String username,String password);  
6.    public void deleteUser(int userId);  
7.    public void modifyUser(int userId,String username,String password);  
8.    public void findUser(int userId);  
9.}  
  
比较常见的对用户进行增删改查。
  
下面我们常见一个实现类,实现这个接口。
  
 
 
Java代码  
1.package com.szy.spring;  
2.  
3.public class UserManagerImpl implements UserManager  
4.{  
5.  
6.    public void addUser(String username, String password)  
7.    {  
8.        System.out.println("--------UserManagerImpl.addUser()----------");  
9.    }  
10.  
11.    public void deleteUser(int userId)  
12.    {  
13.        System.out.println("--------UserManagerImpl.deleteUser()----------");  
14.    }  
15.  
16.    public void findUser(int userId)  
17.    {  
18.        System.out.println("--------UserManagerImpl.findUser()----------");  
19.    }  
20.  
21.    public void modifyUser(int userId, String username, String password)  
22.    {  
23.        System.out.println("--------UserManagerImpl.modifyUser()----------");  
24.    }  
25.}  
  
  
  
每个方法仅仅是输出一句话。
  
下面我们定义一个客户端类来调用这些方法。
  
 
 
Java代码  
1.package com.szy.spring;  
2.  
3.public class Client  
4.{  
5.    public static void main(String[] args)  
6.    {  
7.        UserManager userManager=new UserManagerImpl();  
8.        userManager.addUser("coolszy", "kuka");  
9.    }  
10.}  
  
  
  
运行正常输出我们期望的结果。
  
下面我们需要加入安全性检查,就是调用方法前我们需要进行验证,比较常见的就是权限验证,验证用户是否拥有权限,
  
比较常见的做法就是在UserManagerImpl类中定义一个检查安全性的方法:
  
 
 
Java代码  
1.public void checkSecurity()  
2.    {  
3.        System.out.println("--------UserManagerImpl.checkSecurity()----------");  
4.    }  
  
然后在每个方法中都要调用这个方法。但是这样不符合开-闭原则(Open-Closed principle,简称OCP)。因此我们可以使用代理类来实现这个功能。代理模式很显著的特征就是和目标对象的接口一致。在代理类中我们可以控制目标对象。要控制目标对象我们必须有一个目标对象的引用。为了灵活我们可以把目标对象传到方法中,而不是在方法中实例化。同时我们把安全性检查的代码也放到代理类中,在调用每个方法之前调用这个检查方法,通过代理对我们以前的类没有破坏。
  
 
 
Java代码  
1.package com.szy.spring;  
2.  
3.public class UserManagerImplProxy implements UserManager  
4.{  
5.    private UserManager userManager;  
6.      
7.    public UserManagerImplProxy(UserManager userManager)  
8.    {  
9.        this.userManager = userManager;  
10.    }  
11.    public void addUser(String username, String password)  
12.    {  
13.        checkSecurity();  
14.        this.userManager.addUser(username, password);  
15.    }  
16.    public void deleteUser(int userId)  
17.    {  
18.        checkSecurity();  
19.        this.userManager.deleteUser(userId);  
20.    }  
21.    public String findUser(int userId)  
22.    {  
23.        checkSecurity();  
24.        return this.userManager.findUser(userId);  
25.    }  
26.    public void modifyUser(int userId, String username, String password)  
27.    {  
28.        checkSecurity();  
29.        this.userManager.modifyUser(userId, username, password);  
30.    }  
31.    public void checkSecurity()  
32.    {  
33.        System.out.println("--------UserManagerImpl.checkSecurity()----------");  
34.    }  
35.}  
  
  
  
下面修改客户端类。
  
 
 
Java代码  
1.UserManager userManager=new UserManagerImplProxy(new UserManagerImpl());  
2.        userManager.addUser("coolszy", "kuka");  
  
  
  
这样总的来说比较灵活。这个依赖关系是我们自己做的,我们完全可以交给spring处理。
  
按照上面的这种做法有一个缺点,如果接口中方法很多,那么我们实现每一个方法都要添加检查方法checkSecurity(),影响了我们的业务处理。采用静态代理模式我们是没法解决的,这时我们需要使用AOP思想。
  
  
 
 
 
 
Spring学习笔记(13)----动态代理模式分析演示
-----------------------------------------------
上一节演示的是静态代理模式,本节演示的是静态代理模式,既然是动态,那么就不存在UserManagerImplProxy类。
  
使用动态代理我们需要声明一个类SecurityHandler,这个类要实现InvocationHandler接口。
  
在类中定义一个产生动态代理的方法newProxy();同时把我们验证的代码放到这个类中。通过SecurityHandler,当我们调用方法时默认会调用SecurityHandler类invoke方法,我们在这个方法中进行安全性检查,检查通过后在调用真实的方法。需要注意的是目标对象接口中的部分方法是存在返回值的。
  
 
 
Java代码  
1.package com.szy.spring;  
2.  
3.import java.lang.reflect.InvocationHandler;  
4.import java.lang.reflect.Method;  
5.import java.lang.reflect.Proxy;  
6.  
7.public class SecurityHandler implements InvocationHandler  
8.{  
9.    private Object targetObject;  
10.      
11.    public Object newProxy(Object targetObject)  
12.    {  
13.        this.targetObject=targetObject;  
14.        //返回动态代理  
15.        return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),  
16.                                      targetObject.getClass().getInterfaces(),  
17.                                      this);  
18.    }  
19.    public Object invoke(Object proxy, Method method, Object[] args)  
20.            throws Throwable  
21.    {  
22.        checkSecurity();  
23.        Object ret=null;  
24.        try 
25.        {  
26.            //调用目标对象的真实方法  
27.            ret=method.invoke(this.targetObject, args);  
28.            //ret接受存在的返回值,不存在返回值则为Null  
29.        } catch (Exception e)  
30.        {  
31.            e.printStackTrace();  
32.        }  
33.        return null;  
34.    }  
35.    public void checkSecurity()  
36.    {  
37.        System.out.println("--------UserManagerImpl.checkSecurity()----------");  
38.    }  
39.}  
  
  
  
使用

猜你喜欢

转载自kouhao123.iteye.com/blog/1633481
今日推荐