Spring基础之IoC
IoC(控制反转)就是将原来应用程序要做的事情,交给IoC容器去做。组件不是由应用程序来创建和配置,而是交给IoC容器去做。
DI(依赖注入)IoC的具体实现,就是将调用者需要用到的类,交给容器去创建和配置,在运行期间,动态的自动填充给调用者。(军区主建,战区主战。)
上面提到的交给IoC容器去创建和配置的对象,就是“bean”,“bean”可以是pojo,dao,service,action等等需要管理的对象。
Spring使用工厂模式来创建bean,这个工厂类叫做BeanFactory,但我们大多时间使用它的子类ApplicationContext,用它来创建产品(即bean)。获取ApplicationContext有三种方式:ClassPathXmlApplicationContext 、FileSystemXmlApplicationContext 、XmlWebApplicationContext。
BeanFactory和ApplicationContext的区别:
- ApplicationContext会预先实例化,但耗内存
- BeanFactory实例化较晚,但速度慢
- ApplicationContext在服务启动时就会检验XML文件的正确性,不会产生装载时运行错误。
- BeanFactory在启动时并不会检验XML文件的正确性,只有在获取bean时才会,这时有可能会出现装载错误。
- 大多数场景使用ApplicationContext
Bean由Sping容器管理,它有一些自己的属性,包括id,name,全限定类名,创建模式,初始化和销毁方法、自动装配模式、依赖检查模式、构造参数值、属性值、所依赖的其他bean等等
- id是唯一标志一个bean的。在一个bean生成的过程中,如果有id,那么自然最好。如果没有设置id,只设置了name属性(name属性可以设置多个,比如: a,b,c),那么就把name属性中的第一个取出来,作为id;
- 如果id和name都没有设置(例如@Service),那么系统会有一个默认生成id的方式,就是短类名。比如:com.abc.T.class的短类名就是T(Spring取出短类名之后会进行转化,转换成java常用的参数命名形式,比如:AtTen会被转化成atTen)
注入方式分为三种:
- set注入
- 构造方法注入
- 接口注入
下面为set注入,自动装载:
<?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.1.xsd">
<bean id="dog" class="com.wmj.autowire.Dog">
<property name="name" value="小黄"/>
<property name="age" value="3"></property>
</bean>
<bean id="master" class="com.wmj.autowire.Master" autowire="byName">
<property name="name" value="wmj"/>
</bean>
</beans>
//主人
public class Master {
private String name;
private Dog dog;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Dog getDog() {
return dog;
}
public void setDog(Dog dog) {
this.dog = dog;
}
}
//宠物狗
public class Dog {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
//调用
public class App {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("com/wmj/autowire/beans.xml");
Master master = (Master) ac.getBean("master");
System.out.println(master.getName()+"养"+master.getDog().getName());
}
}
//运行结果
wmj养小黄
继承配置:
//bean配置
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<bean id="student" class="com.wmj.inherit.Student">
<property name="name" value="刘德华"/>
<property name="age" value="60"/>
</bean>
<bean id="graduate" parent="student" class="com.wmj.inherit.Graduate">
<property name="degree" value="学士"/>
<property name="name" value="张学友"/>
</bean>
</beans>
//学生
public class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//毕业生
public class Graduate extends Student{
private String degree;
public String getDegree() {
return degree;
}
public void setDegree(String degree) {
this.degree = degree;
}
}
}
//调用
public class App {
public static void main(String[] args) {
BeanFactory factory = new XmlBeanFactory(new ClassPathResource("com/wmj/inherit/beans.xml"));
Graduate gd = (Graduate) factory.getBean("graduate");
System.out.println(gd.getName()+" "+gd.getAge()+" "+gd.getDegree());
}
}
//运行结果
张学友 60 学士
集合注入配置配置:
<bean id="department" class="com.wmj.collection.Department">
<property name="name" value="技术部"/>
<!-- 配置properties -->
<property name="pp">
<props>
<prop key="pp1">1111</prop>
<prop key="pp2">2222</prop>
</props>
</property>
<!-- 给数组注入值 -->
<property name="empname">
<list>
<value>小明</value>
<value>大明</value>
<value>老明</value>
</list>
</property>
<!-- 给list注入值 -->
<property name="emplist">
<list>
<ref bean="emp1"/>
<ref bean="emp2"/>
</list>
</property>
<!-- 给set注入值 -->
<property name="empset">
<set>
<ref bean="emp1"/>
<ref bean="emp2"/>
</set>
</property>
<!-- 给map注入值 -->
<property name="empmap">
<map>
<entry key="1" value-ref="emp1"/>
<entry key="2" value-ref="emp2"/>
</map>
</property>
</bean>
<!-- 也可以通过构造函数注入 -->
<bean id="emp3" class="com.wmj.collection.Employee">
<constructor-arg index="0" type="java.lang.String" value="杰哥"/>
<constructor-arg index="1" type="java.lang.Integer" value="22"/>
</bean>
<bean id="emp1" class="com.wmj.collection.Employee">
<property name="name" value="奥巴马"/>
<property name="age" value="60"/>
</bean>
<bean id="emp2" class="com.wmj.collection.Employee">
<property name="name" value="卡梅伦"/>
<property name="age" value="65"/>
</bean>
public class Department {
private String name;
private String[] empname;
private List<Employee> emplist;
private Set<Employee> empset;
private Map<String,Employee> empmap;
private Properties pp;
public Properties getPp() {
return pp;
}
public void setPp(Properties pp) {
this.pp = pp;
}
public Map<String, Employee> getEmpmap() {
return empmap;
}
public void setEmpmap(Map<String, Employee> empmap) {
this.empmap = empmap;
}
public Set<Employee> getEmpset() {
return empset;
}
public void setEmpset(Set<Employee> empset) {
this.empset = empset;
}
public List<Employee> getEmplist() {
return emplist;
}
public void setEmplist(List<Employee> emplist) {
this.emplist = emplist;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String[] getEmpname() {
return empname;
}
public void setEmpname(String[] empname) {
this.empname = empname;
}
}
public class Employee {
private String name;
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Employee(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Employee(){
}
}
public class App {
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext ac = new ClassPathXmlApplicationContext("com/wmj/collection/beans.xml");
Department dm = (Department) ac.getBean("department");
System.out.println(dm.getName());
for(String ename: dm.getEmpname()){
System.out.println(ename);
}
System.out.println("*************通过list取数据********************");
for(Employee emp: dm.getEmplist()){
System.out.println(emp.getName());
}
System.out.println("*************通过set取数据********************");
for(Employee emp: dm.getEmpset()){
System.out.println(emp.getName());
}
System.out.println("*************通过map取数据********************");
//通过entry取
for(Entry<String,Employee> emp:dm.getEmpmap().entrySet()){
System.out.println(emp.getKey()+" "+emp.getValue().getName());
}
//通过iterator迭代器取数据
Map<String,Employee> empmap = dm.getEmpmap();
Iterator it = (Iterator) empmap.keySet().iterator();
while(it.hasNext()){
String key = (String) it.next();
Employee emp = empmap.get(key);
System.out.println("key="+key+" value="+emp.getName()+" "+emp.getAge());
}
System.out.println("*************通过properties取数据********************");
Properties pp = dm.getPp();
for(Entry<Object,Object> entry: pp.entrySet()){
System.out.println(entry.getKey().toString()+" "+entry.getValue().toString());
}
System.out.println("*************通过Enumeration取数据********************");
Enumeration en = pp.keys();
while(en.hasMoreElements()){
String key = (String) en.nextElement();
System.out.println(key+" "+pp.getProperty(key));
}
}
}
bean可以配置多种类型的对象,例如数据源,action,ftp服务器,邮件服务器等等,下面以配置简单数据源作为栗子。
<?xml version="1.0" encoding="utf-8"?>
<!--
- Application context definition for JPetStore's business layer.
- Contains bean references to the transaction manager and to the DAOs in
- dataAccessContext-local/jta.xml (see web.xml's "contextConfigLocation").
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<!--引入db.properties文件 -->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>com/wmj/dispacher/db.properties</value>
</list>
</property>
</bean>
<bean id="dbutil" class="com.wmj.dispacher.DBUtil">
<property name="drivername" value="${drivername}"/>
<property name="url" value="${url}"/>
<property name="name" value="${name}"/>
<property name="pwd" value="${pwd}"/>
</bean>
</beans>
public class DBUtil {
private String drivername;
private String url;
private String name;
private String pwd;
public String getDrivername() {
return drivername;
}
public void setDrivername(String drivername) {
this.drivername = drivername;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
//文件db.properties
drivername=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/xuanke
name=root
pwd=940130
public class App {
public static void main(String[] args) {
ApplicationContext ac = new ClassPathXmlApplicationContext("com/wmj/dispacher/beans.xml");
DBUtil db = (DBUtil) ac.getBean("dbutil");
System.out.println(db.getDrivername()+" "+db.getName());
}
}
上一篇: kaggle house price
下一篇: 用递归实现生成Gray码的算方法