Spring--IOC(一)
第一节:spring ioc简介
IOC(控制反转:Inverse of Control ) ,又称作 依赖注入,是一种重要的面向对象编程的法则来削减计算机程序
的耦合问题,也是轻量级的 Spring 框架的核心。
一些对象与其之间的依赖关系
public class ZhangSan implements Tester{ public void test(){ System.out.println("张三-测试程序"); } } public class Lisi implements Tester{ public void test(){ System.out.println("李四-测试程序"); } } public interface Tester { public void test(); } public class JavaWork { private Tester tester; public void setTester(Tester tester) { this.tester = tester; } public void doTest(){ /*ZhangSan zhangsan=new ZhangSan(); zhangsan.test();*/ tester.test(); //如果测试人员换成lisi就要改代码,改为使用接口方式,降低对象之间的耦合度 } }
使用普通方式的业务执行代码与使用spring控制对象的代码,beans.xml 使用反射机制来创建对象。
public class Test { /** * 主管执行命令 * @param args */ public static void main(String[] args) { JavaWork javaWork=new JavaWork(); // javaWork.setTester(new ZhangSan()); javaWork.setTester(new Lisi()); javaWork.doTest(); } } public class Test2 { public static void main(String[] args) { ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml"); JavaWork javaWork=(JavaWork)ac.getBean("javaWork"); javaWork.doTest(); } }
<?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="zhangsan" class="com.java1234.service.ZhangSan"></bean> <bean id="lisi" class="com.java1234.service.Lisi"></bean> <bean id="javaWork" class="com.java1234.service.JavaWork"> <!-- 给JavaWork类中的属性tester注入对象 ,ref对应bean id--> <property name="tester" ref="lisi"></property> </bean> </beans>
第三节:装配一个 bean
第四节:依赖注入
1,属性注入;
2,构造函数注入;(通过类型;通过索引;联合使用,不常用)
3,工厂方法注入;(非静态工厂,静态工厂)
4,泛型依赖注入;(Spring4 整合 Hibernate4 的时候顺带讲), 参考:http://jinnianshilongnian.iteye.com/blog/1989330
例子用到的类
public class People { private int id; private String name; private int age; public People() { super(); // TODO Auto-generated constructor stub } public People(int id, String name, int age) { super(); this.id = id; this.name = name; this.age = age; } 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 int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "People [id=" + id + ", name=" + name + ", age=" + age + "]"; } } public class PeopleFactory { public People createPeople(){ People p=new People(); p.setId(5); p.setName("小七"); p.setAge(77); return p; } } public class PeopleFactory2 { public static People createPeople(){ People p=new People(); p.setId(8); p.setName("小八"); p.setAge(88); return p; } } public class Test2 { public static void main(String[] args) { ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml"); People people=(People)ac.getBean("people"); System.out.println(people); // 属性注入 People people2=(People)ac.getBean("people2"); System.out.println(people2); // 构造方法注入 People people3=(People)ac.getBean("people3"); System.out.println(people3); People people4=(People)ac.getBean("people4"); System.out.println(people4); People people5=(People)ac.getBean("people5"); System.out.println(people5); // 工厂方法注入 People people7=(People)ac.getBean("people7"); System.out.println(people7); People people8=(People)ac.getBean("people8"); System.out.println(people8); } }
在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 --> <bean id="people" class="com.java1234.entity.People"></bean> <!-- 依赖注入,1,属性注入; --> <bean id="people2" class="com.java1234.entity.People"> <property name="id" value="1"></property> <property name="name" value="张三"></property> <property name="age" value="11"></property> </bean> <!-- 2,构造函数注入;(通过类型;通过索引;联合使用) --> <bean id="people3" class="com.java1234.entity.People"> <constructor-arg type="int" value="2"></constructor-arg> <constructor-arg type="String" value="李四"></constructor-arg> <constructor-arg type="int" value="22"></constructor-arg> </bean> <bean id="people4" class="com.java1234.entity.People"> <constructor-arg index="0" value="3"></constructor-arg> <constructor-arg index="1" value="王五"></constructor-arg> <constructor-arg index="2" value="55"></constructor-arg> </bean> <bean id="people5" class="com.java1234.entity.People"> <constructor-arg index="0" type="int" value="4"></constructor-arg> <constructor-arg index="1" type="String" value="招六"></constructor-arg> <constructor-arg index="2" type="int" value="66"></constructor-arg> </bean> <!-- 3,工厂方法注入;(非静态工厂,需要定义一个工厂bean) --> <bean id="peopleFactory" class="com.java1234.factory.PeopleFactory"></bean> <bean id="people7" factory-bean="peopleFactory" factory-method="createPeople"></bean> <!-- 静态工厂,不需要定义工厂bean,直接用类名.方法 --> <bean id="people8" class="com.java1234.factory.PeopleFactory2" factory-method="createPeople"></bean> </beans>
第五节:注入参数
1,基本类型值;
2,注入 bean;
3,内部 bean;
4,null 值;
5,级联属性;
6,集合类型属性;
public class Dog { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } public class People { private int id; private String name; private int age; private Dog dog ; private List<String> hobbies=new ArrayList<String>(); private Set<String> loves=new HashSet<String>(); private Map<String,String> works=new HashMap<String,String>(); private Properties addresses=new Properties(); public People() { super(); // TODO Auto-generated constructor stub } public People(int id, String name, int age) { super(); this.id = id; this.name = name; this.age = age; } public Set<String> getLoves() { return loves; } public void setLoves(Set<String> loves) { this.loves = loves; } public List<String> getHobbies() { return hobbies; } public void setHobbies(List<String> hobbies) { this.hobbies = hobbies; } public Map<String, String> getWorks() { return works; } public void setWorks(Map<String, String> works) { this.works = works; } public Properties getAddresses() { return addresses; } public void setAddresses(Properties addresses) { this.addresses = addresses; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } 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 int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "People [id=" + id + ", name=" + name + ", age=" + age + ", dog=" + dog + ", hobbies=" + hobbies + ", loves=" + loves + ", works=" + works + ", addresses=" + addresses + "]"; } } public class T { private ApplicationContext ac; @Before public void setUp() throws Exception { ac=new ClassPathXmlApplicationContext("beans.xml"); } // 基本类型值 @Test public void test1() { People people=(People)ac.getBean("people1"); System.out.println(people); } // 注入bean @Test public void test2() { People people=(People)ac.getBean("people2"); System.out.println(people); } // 内部bean @Test public void test3() { People people=(People)ac.getBean("people3"); System.out.println(people); } // 注入null @Test public void test4() { People people=(People)ac.getBean("people4"); System.out.println(people); } // 级联属性 @Test public void test5() { People people=(People)ac.getBean("people5"); System.out.println(people); } // 注入集合 @Test public void test6() { People people=(People)ac.getBean("people6"); System.out.println(people); } }
<?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="people1" class="com.java1234.entity.People"> <property name="id" value="1"></property> <property name="name" value="张三"></property> <property name="age" value="11"></property> </bean> <!-- 注入bean --> <bean id="dog1" class="com.java1234.entity.Dog"> <property name="name" value="Jack"></property> </bean> <bean id="people2" class="com.java1234.entity.People"> <property name="id" value="1"></property> <property name="name" value="张三"></property> <property name="age" value="11"></property> <property name="dog" ref="dog1"></property> </bean> <!-- 内部bean --> <bean id="people3" class="com.java1234.entity.People"> <property name="id" value="1"></property> <property name="name" value="张三"></property> <property name="age" value="11"></property> <property name="dog"> <bean class="com.java1234.entity.Dog"> <property name="name" value="Tom"></property> </bean> </property> </bean> <!-- 注入null --> <bean id="people4" class="com.java1234.entity.People"> <property name="id" value="1"></property> <property name="name" value="张三"></property> <property name="age" value="11"></property> <property name="dog"> <null></null> </property> </bean> <!-- 级联属性 需要在People类中创建对象dog=new Dog(),否则会报错--> <!-- <bean id="people5" class="com.java1234.entity.People"> <property name="id" value="1"></property> <property name="name" value="张三"></property> <property name="age" value="11"></property> <property name="dog.name" value="Jack2"></property> </bean> --> <!-- 注入集合 --> <bean id="people6" class="com.java1234.entity.People"> <property name="id" value="1"></property> <property name="name" value="张三"></property> <property name="age" value="11"></property> <property name="dog" ref="dog1"></property> <property name="hobbies"> <list> <value>唱歌</value> <value>跳舞</value> </list> </property> <property name="loves"> <set> <value>唱歌2</value> <value>跳舞2</value> </set> </property> <property name="works"> <map> <entry> <key><value>上午</value></key> <value>写代码</value> </entry> <entry> <key><value>下午</value></key> <value>测试代码</value> </entry> </map> </property> <property name="addresses"> <props> <prop key="address1">aaaaa</prop> <prop key="address2">bbbbb</prop> </props> </property> </bean> </beans>
第六节:Spring 自动装配
通过配置 default-autowire 属性,Spring IOC 容器可以自动为程序注入 bean;默认是 no,不启用自动装配;
default-autowire 的类型有 byName,byType,constructor;
byName:通过名称进行自动匹配;
byType:根据类型进行自动匹配;
constructor:和 byType 类似,只不过它是根据构造方法注入而言的,根据类型,自动注入;
建议:自动装配机制慎用,它屏蔽了装配细节,容易产生潜在的错误;
default-autowire="constructor" 这里面配置各种装配方式
<?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" default-autowire="constructor"> <!-- constructor:和 byType 类似,只不过它是根据构造方法注入而言的,根据类型,自动注入;People类中需要有个Dog的构造方法 --> <bean id="dog2" class="com.java1234.entity.Dog"> <property name="name" value="Jack"></property> </bean> <!-- byName:通过名称进行自动匹配; bean id 和 People类中的属性名dog相同--> <!-- <bean id="dog" class="com.java1234.entity.Dog"> <property name="name" value="Tom"></property> </bean> --> <bean id="people1" class="com.java1234.entity.People"> <property name="id" value="1"></property> <property name="name" value="张三"></property> <property name="age" value="11"></property> </bean> </beans>
public class T { private ApplicationContext ac; @Before public void setUp() throws Exception { ac=new ClassPathXmlApplicationContext("beans.xml"); } @Test public void test1() { People people=(People)ac.getBean("people1"); System.out.println(people); } } package com.java1234.entity; public class People { private int id; private String name; private int age; private Dog dog; public People() { super(); // TODO Auto-generated constructor stub } public People(Dog dog) { super(); System.out.println("constructor"); this.dog = dog; } 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 int getAge() { return age; } public void setAge(int age) { this.age = age; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } @Override public String toString() { return "People [id=" + id + ", name=" + name + ", age=" + age + ", dog=" + dog.getName() + "]"; } } public class Dog { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
第七节:方法注入
Spring bean 作用域默认是 单例 singleton; 可以通过配置 prototype ,实现多例;
方法注入 lookup-method
<?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"> <!-- 单例 singleton; 多例 prototype ,测试 --> <bean id="dog" class="com.java1234.entity.Dog" scope="prototype"> <property name="name" value="Jack"></property> </bean> <bean id="people1" class="com.java1234.entity.People"> <property name="id" value="1"></property> <property name="name" value="张三"></property> <property name="age" value="11"></property> <!-- spring 通过cglib封装的,dog 都是单例 --> <!-- <property name="dog" ref="dog"></property> --> <!-- People中的getDog改成抽象方法,通过spring动态注入 ,dog设置为prototype时每次都是新创建的,了解一下--> <lookup-method name="getDog" bean="dog"/> </bean> </beans>
public class T { private ApplicationContext ac; @Before public void setUp() throws Exception { ac=new ClassPathXmlApplicationContext("beans.xml"); } @Test public void test1() { People people=(People)ac.getBean("people1"); People people2=(People)ac.getBean("people1"); //内部bean都是单例,除非采用方法注入 System.out.println(people.getDog()==people2.getDog()); //单例,多例测试 System.out.println(ac.getBean("dog")==ac.getBean("dog")); } } public abstract class People { private int id; private String name; private int age; private Dog dog; 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 int getAge() { return age; } public void setAge(int age) { this.age = age; } public abstract Dog getDog(); /* public Dog getDog(){ return dog; }*/ public void setDog(Dog dog) { this.dog = dog; } @Override public String toString() { return "People [id=" + id + ", name=" + name + ", age=" + age + ", dog=" + dog.getName() + "]"; } } public class Dog { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
第八节:方法替换
<?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="people1" class="com.java1234.entity.People"> <property name="id" value="1"></property> <property name="name" value="张三"></property> <property name="age" value="11"></property> <!-- 调用people1中的getDog 时就会调用people2中的reimplement替换方法 --> <replaced-method name="getDog" replacer="people2"></replaced-method> </bean> <!-- People2实现接口MethodReplacer,重写替换方法 --> <bean id="people2" class="com.java1234.entity.People2"></bean> </beans>
public class People2 implements MethodReplacer { @Override public Object reimplement(Object arg0, Method arg1, Object[] arg2) throws Throwable { Dog dog=new Dog(); dog.setName("Tom"); return dog; } } public class T { private ApplicationContext ac; @Before public void setUp() throws Exception { ac=new ClassPathXmlApplicationContext("beans.xml"); } @Test public void test1() { People people=(People)ac.getBean("people1"); System.out.println(people.getDog().getName()); } } public class People { private int id; private String name; private int age; private Dog dog; 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 int getAge() { return age; } public void setAge(int age) { this.age = age; } public Dog getDog() { Dog dog=new Dog(); dog.setName("Jack"); return dog; } public void setDog(Dog dog) { this.dog = dog; } @Override public String toString() { return "People [id=" + id + ", name=" + name + ", age=" + age + ", dog=" + dog.getName() + "]"; } } public class Dog { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
第九节:bean之间的关系
1,继承;
2,依赖;
3,引用;
<?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="dog" class="com.java1234.entity.Dog"> <property name="name" value="jack"></property> </bean> <!-- 定义一个父类,有公共属性 --> <bean id="abstractPeople" class="com.java1234.entity.People" abstract="true"> <property name="className" value="高三5班"></property> <property name="age" value="19"></property> </bean> <!-- 子类继承父类的属性,也可以重写 --> <!-- 依赖关系 depends-on="autority" 先加载autority这个bean --> <bean id="zhangsan" parent="abstractPeople" depends-on="autority"> <property name="id" value="1"></property> <property name="name" value="张三"></property> </bean> <bean id="lisi" parent="abstractPeople"> <property name="id" value="2"></property> <property name="name" value="李四"></property> <property name="age" value="20"></property> <property name="dog" ref="dog"></property> <!-- bean 之间的引用关系ref="" --> </bean> <bean id="autority" class="com.java1234.service.Authority"></bean>
public class T { private ApplicationContext ac; @Before public void setUp() throws Exception { ac=new ClassPathXmlApplicationContext("beans.xml"); } @Test public void test1() { People zhangsan=(People)ac.getBean("zhangsan"); System.out.println(zhangsan); People lisi=(People)ac.getBean("lisi"); System.out.println(lisi); } } public class Authority { public Authority() { System.out.println("获取权限"); } } public class People { private int id; private String name; private int age; private String className; private Dog dog; public People() { System.out.println("初始化People"); } 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 int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } @Override public String toString() { return "People [id=" + id + ", name=" + name + ", age=" + age + ", className=" + className + ", dog=" + dog + "]"; } }
第十节:bean作用范围
1,singleton Spring ioc 容器中仅有一个 Bean实例,Bean 以单例的方式存在;
2,prototype 每次从容器中调用 Bean时,都返回一个新的实例;
3,request 每次 HTTP 请求都会创建一个新的 Bean; (前面2个重点,后面几个了解)
4,session 同一个 HTTP Session 共享一个 Bean;
5,global session 同一个全局 Session 共享一个 Bean,一般用于 Portlet 应用环境;
6,application 同一个 Application 共享一个 Bean;

浙公网安备 33010602011771号