Java的反射机制可以说是在Spring中发挥的淋漓尽致,下面要看的代码就是通过反射机制来实现向一个类注入其实际依赖的类型,这个过程的实现会交由Spring容器来帮我们完成。
JavaBean中针对属性一般都有一组设置/获取方法(setXXX/getXXX),这两个方法可以由IDE给我们自动产生,当然你也可以手动进行编写,这是你的自由,下面的例子就是Spring中利用setter方法来实现依赖注入。
源代码如下:
package com.pp; //一个普通的JavaBean public class Person { //人的名字 private String S_name; private String S_addr; private int age; //getter方法 public int getS_Age() { return age; } //setter方法 public void setS_Age(int age) { this.age = age; } //setter方法 public String getaddr() { return S_addr; } //getter方法 public void setaddr(String addr) { S_addr = addr; } //构造函数 public Person(){} //getter方法 public String getName() { return S_name; } //setter方法 public void setName(String name) { S_name = name; }; }
有了这个普通的JavaBean,我们要利用Spring容器来实现属性的注入,这里就需要Spring的配置文件,Spring的配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="sentence" class="com.pp.Sentence"/> <bean id="person" class="com.pp.Person"> <!-- 从这里可以看出的是属性名是setter方法里去掉set的部分,即setXXX中的XXX而与具体的属性无关 --> <property name="name" value="pptest"></property> <!-- 这里你完全可以把setaddr里的参数改成setaddr(String name),并不会报错,因为判断的依据是setXXX即XXX --> <!-- 但如果你改成setS_addr这里就要错了,不信你可以试,如果改成setS_addr,则下面的name需要改成S_addr --> <property name="addr" value="Beijing"></property> <!-- 这里就是上面的一个例子,类的属性名为age,但这里的name却为S_Age --> <!-- 同时这里也要说明的一个问题是类里面为int,但这里却是字符串类型,这个你不用担心,Spring在进行注入时会自动根据参数的类型进行类型 的转化 --> <property name="S_Age" value="22"></property> </bean> </beans>
配置文件中我已经注释的很清楚了,就不做说明了
下面是一个测试文件
import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.ClassPathResource; public class MainTest { public static void main(String[] args) { BeanFactory factory=new XmlBeanFactory(new ClassPathResource("person.xml")); Person person=(Person)factory.getBean("person"); System.out.println(person.getName()); System.out.println(person.getaddr()); System.out.println(person.getS_Age()); } }
如果一切正常的话,应该会打印出如下的结果:
pptest
Beijing
22
上面向类里面注入的均是内置类型,其实不仅可以注入内置类型,还可以向里面注入外部类对象,下面就是一个例子,只显示增加的部份,增加的部分,是假设每一个人均有说一句话,这句话的实际内容是由Sentence这个类决定的
源代码:
//这是一个普通的类,当然这样设计不好,在此仅为说明一下 public class Sentence{ //类里面的方法,表示每一个人均说的是同样的一句话 public void say() { System.out.println("Hello"); } }
下面是在类Person使用刚才的Sentence这个类,以下只列出新增代码
//代表要说的话 private Sentence sce; //setter方法 public Sentence getSce() { return sce; } //getter方法 public void setSce(Sentence sce) { this.sce = sce; }
以下是配置文件,同样也只列出新增的一部份
<bean id="sentence" class="com.pp.Sentence"/> <bean id="person" class="com.pp.Person"> <!-- 从这里可以看出的是属性名是setter方法里去掉set的部分,即setXXX中的XXX而与具体的属性无关 --> <property name="name" value="pptest"></property> <!-- 这里你完全可以把setaddr里的参数改成setaddr(String name),并不会报错,因为判断的依据是setXXX即XXX --> <!-- 但如果你改成setS_addr这里就要错了,不信你可以试,如果改成setS_addr,则下面的name需要改成S_addr --> <property name="addr" value="Beijing"></property> <!-- 这里就是上面的一个例子,类的属性名为age,但这里的name却为S_Age --> <!-- 同时这里也要说明的一个问题是类里面为int,但这里却是字符串类型,这个你不用担心,Spring在进行注入时会自动根据参数的类型进行类型 的转化 --> <property name="S_Age" value="22"></property> <!-- 引入在外部定义的bean,这里就是上面的一个bean的id --> <property name="Sce" ref="sentence"></property> </bean>
测试文件里里面只需填加一行即可:
person.getSce().say();
最终的结果如下:
pptest
Beijing
22
Hello
上面的配置文件中,是用外部Bean注入的,我们也可以使用内部Bean注入,所谓内部Bean注入,是直接把Bean的定义写在property属性里,如下是更改后的配置文件
<!-- <bean id="sentence" class="com.pp.Sentence"/> --> <bean id="person" class="com.pp.Person"> <!-- 从这里可以看出的是属性名是setter方法里去掉set的部分,即setXXX中的XXX而与具体的属性无关 --> <property name="name" value="pptest"></property> <!-- 这里你完全可以把setaddr里的参数改成setaddr(String name),并不会报错,因为判断的依据是setXXX即XXX --> <!-- 但如果你改成setS_addr这里就要错了,不信你可以试,如果改成setS_addr,则下面的name需要改成S_addr --> <property name="addr" value="Beijing"></property> <!-- 这里就是上面的一个例子,类的属性名为age,但这里的name却为S_Age --> <!-- 同时这里也要说明的一个问题是类里面为int,但这里却是字符串类型,这个你不用担心,Spring在进行注入时会自动根据参数的类型进行类型 的转化 --> <property name="S_Age" value="22"></property> <!-- 引入在外部定义的bean,这里就是上面的一个bean的id <property name="Sce" ref="sentence"></property>--> <property name="Sce"> <!-- 内部的Bean不能被外部的Bean引用,因此在里面加入id属性,是没有什么用的,内部Bean只能供本类使用,这里就是Person类的一个对象 --> <bean class="com.pp.Sentence"></bean> </property> </bean>
测试文件可以不加任何改动,但最终的运行结果是一样的