spring应用之装配Bean的方式(五)
Spring装配Bean一般有两种方式,一种是通过Xml进行配置,另外一种是通过注解进行配置。
xml的方式
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> </beans>
这里引入了Spring的xml约束,这些文件会对Spring Bean的一些元素,上面引入了Beans的定义,他是根元素,而XSD文件也被引入了,这样他所定义的元素可以定义对应的Spring Bean。
装配简易的值
<bean id="person" class="pro.jamal.blog.demo5.Person"> <property name="name" value="yongjar"/> <property name="age" value="20"/> </bean>
这是一个简易的配置:
id属性是Spring找到的这个Bean的编号,不过id不是必须属性,如果没有证明它,那么spring将会采用“全限定名#{number}”的格式生成编号。
class是一个类的全限定名。
property元素是定义的属性,其中name属性定义的属性名称,而value是其的值。
装配集合
首先我们定义学生类Sutdent和Address地址类。
package pro.jamal.blog.demo5; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; /** * @author: lyj * @Date: 2019/6/7 */ public class Student { private String name; private Address address; private String[] books; private List<String> hobbies; private Map<String,String> cards; private Set<String> games; private String wife; private Properties info; public void setInfo(Properties info) { this.info = info; } public void setWife(String wife) { this.wife = wife; } public void setCards(Map<String, String> cards) { this.cards = cards; } public void setAddress(Address address) { this.address = address; } public void setHobbies(List<String> hobbies) { this.hobbies = hobbies; } public void setBooks(String[] books) { this.books = books; } public void setGames(Set games) { this.games = games; } public void setName(String name) { this.name = name; } }
package pro.jamal.blog.demo5; /** * @author: lyj * @Date: 2019/6/7 */ public class Address { private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }
xml的配置
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="address" class="pro.jamal.blog.demo5.Address"> <property name="address" value="汕头"/> </bean> <bean id="student" class="pro.jamal.blog.demo5.Student"> <property name="name" value="chris"/> <property name="address" ref="address"/> <property name="books"> <array> <value>傲慢与偏见</value> <value>java入门到精通</value> <value>Think in java</value> </array> </property> <property name="hobbies"> <list> <value>篮球</value> <value>音乐</value> <value>足球</value> </list> </property> <property name="cards"> <map> <entry key="中国银行" value="159949432"/> <entry key="广发银行" value="98454545"/> <entry key="中泰银行" value="31231321"/> </map> </property> <property name="games"> <set> <value>刺激战场</value> <value>LOL</value> <value>DOTA</value> </set> </property> <property name="wife"><null/></property> <property name="info"> <props> <prop key="学号" >2659548</prop> <prop key="手机号" >15984943216</prop> <prop key="sex" >男</prop> </props> </property> </bean> </beans>
这些配置具体写一下,也就知道其中的含义了,这里不做解释。
测试
public class Client { public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("pro/jamal/blog/demo5/bean.xml"); Student bean = context.getBean(Student.class); System.out.println(bean.toString()); } }
第二种,通过注解进行bean的装配,更多时候我们不推荐使用XML的方式去装配Bean,更多时候会考虑使用注解去装配Bean,因为更方便,而且功能也更加强大,他不但能实现XML的功能,也提供了自动装配的功能,采用了自动装配后,程序员所需要做的决断就少了,更加有利于对程序的开始,这就是”约定大于配置”的开发原则。
在Spring中,他提供了两种方式来让Spring Ioc容器发现Bean。
* 组件扫描:通过定义资源的方式,让Spring Ioc容器扫描对应的包,从而把Bean装配起来。
* 自动装配: 通过注解定义,使得一些依赖关系可以通过注解来完成。
组件扫描示例
首先定义一个POJO类,
package pro.jamal.blog.demo5.annotation; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * @author: lyj * @Date: 2019/6/8 */@Component(value = "staff")
public class Staff {@Value("2")
private int id;@Value("yongjar")
private String name;
@Value("8000.0")
private float salary; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public float getSalary() { return salary; } public void setSalary(float salary) { this.salary = salary; } }
* @Component(value = "staff") 代表Spring Ioc会把这个类扫描生成Bean实例,而其中value属性代表这个类在Spring中的id,相当于XML方式定义的id,也可以简写成@Component(“staff”),value可以忽略不写,甚至也可以写为@@Component,对于不写value的值,Spring Ioc容器就默认类名的形式作为id,为其生成对象,配置到容器中。
* @Value 代表值的注入,这里只是简单地注入一些值。
现在有这个类,但是还不能测试,因为Spring Ioc并不知道需要去哪里扫描对象,这时候可以使用java Config来告诉它。
package pro.jamal.blog.demo5.annotation; import org.springframework.context.annotation.ComponentScan; /** * @author: lyj * @Date: 2019/6/8 */@ComponentScan
public class PoJoConfig { }
* @ComponentScan 代表进行扫描,默认扫描当前包的路径,PoJo的包名和它保持一致才能扫描,否则是没有用的。
测试使用AnnotationConfigApplicationContext去生成IoC容器。
package pro.jamal.blog.demo5.annotation; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; /** * @author: lyj * @Date: 2019/6/8 */ public class AnnotationClient { public static void main(String[] args) { ApplicationContext context = newAnnotationConfigApplicationContext
(PoJoConfig.class); Staff staff = context.getBean(Staff.class); System.out.println( "id:"+staff.getId() +",name:" + staff.getName() +",salary:" + staff.getSalary() ); } }
这里可以看到使用了AnnotationConfigApplicationContext类去初始化Spring Ioc容器,他的配置项是是PojoConfig类,这样Spring Ioc就会根据注解的配置去解析对应的资源,来生成Ioc容器了。
上面的案例可以看出两个弊端,1对于ComponentScan注解,它只是扫描所在包的java类,但是,更多时候真正需要的是可以扫描所指定的类,2,上面只是注入了一些简单的值,而没有注入对象,同样在现实的开发中注入对象是十分重要的,也是很常见的。这两个问题,在我接下来的blog进行讲解。