依赖注入的三种方式: 1.基于接口注入 2.构造方法注入 3.set注入 基于接口注入: 只要实现制定的接口,那么便创建对象,类似于标示接口,比如说:servlet的pagecontext等,只要实现了servlet接口,那么pagecontext,request,response,ServletContext等就会创建 构造方法注入: 顾名思义,通过构造方法注入对象的属性,这种方式不常用 Set注入: 通过set方法注入对象信息,这个用的最多 ApplicationContext: 通常使用ClassPathXmlApplicationContext这个类来代替XmlBeanFactory FileResource: 得到资源文件(xml)的另一种方式:绝对路径方式,一般使用的不多 综合例子(依赖注入and ClassPathXmlApplicationContext): 程序目标:测试构造方法注入和set注入 Model接口: package yuchen.immit.constructimmit; public interface Model { public String supportData(); } view接口: package yuchen.immit.constructimmit; public interface View { public void render(); } ModelImp实现类: package yuchen.immit.constructimmit; public class ModelImp implements Model { //set注入 private String ownerName; private double balance; //构造方法注入 private String city; public ModelImp(String city){ this.city=city; } public String supportData() { // TODO Auto-generated method stub return "model : \n"+"ownerName :"+this.ownerName+ "\n balance :"+this.balance+"\n city:"+city; } public double getBalance() { return balance; } public void setBalance(double balance) { this.balance = balance; } public String getOwnerName() { return ownerName; } public void setOwnerName(String ownerName) { this.ownerName = ownerName; } } ViewImp: package yuchen.immit.constructimmit; public class ViewImp implements View { private Model model; private Model model2;//构造方法注入 public ViewImp(Model model2){ this.model2=model2; } public void render() { // TODO Auto-generated method stub // String rst=model2.supportData();构造注入的ModelImp对象 String rst=model.supportData(); System.out.println(rst); } public Model getModel() { return model; } public void setModel(Model model) { this.model = model; } } beans.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www./dtd/spring-beans.dtd" > <beans> <bean id="model" class="yuchen.immit.constructimmit.ModelImp"> <constructor-arg > <value>北京</value> </constructor-arg> <property name="ownerName"> <value>yuchen</value> </property> <property name="balance"> <value>1000.67</value> </property> </bean> <bean id="view" class="yuchen.immit.constructimmit.ViewImp"> <constructor-arg> <ref bean="model"></ref> </constructor-arg> <property name="model"> <ref bean="model"></ref> </property> </bean> </beans> Test: package yuchen.immit.constructimmit; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.context.support.ClassPathXmlApplicationContext; import org.springframework.core.io.ClassPathResource; public class Test { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub // ClassPathResource resource=new ClassPathResource ("yuchen/immit/constructimmit/beans.xml"); // XmlBeanFactory factory=new XmlBeanFactory(resource); ClassPathXmlApplicationContext factory=new ClassPathXmlApplicationContext("yuchen/immit/constructimmit/beans.xml"); View view=(View) factory.getBean("view"); view.render(); } } Ioc依赖注入的特点: 1.对spring没有依赖性,程序不依赖于spring指定的Api 2.bean都是单例的,除非在bean的属性修改 3.支持基本类型,引用类型和集合类型 接口: package yuchen.ioccharacteristic; public interface IocCharacteristic { public void display(); } 实现类: package yuchen.ioccharacteristic; import java.util.Map; public class IocCharacteristicImp implements IocCharacteristic { private Map map; public void display() { // TODO Auto-generated method stub System.out.println("display"+this.map); } public Map getMap() { return map; } public void setMap(Map map) { this.map = map; } } beans.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www./dtd/spring-beans.dtd" > <beans> <bean id="ioc" class="yuchen.ioccharacteristic.IocCharacteristicImp" singleton="false"> <property name="map"> <map> <entry key="1"> <value>yuchen</value> </entry> <entry key="2"> <value>liu</value> </entry> <entry key="3"> <value>li</value> </entry> </map> </property> </bean> </beans> Test: package yuchen.ioccharacteristic; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub ClassPathXmlApplicationContext factory=new ClassPathXmlApplicationContext ("yuchen/ioccharacteristic/beans.xml"); IocCharacteristic ic=(IocCharacteristic) factory.getBean("ioc"); IocCharacteristic ic2=(IocCharacteristic) factory.getBean("ioc"); //默认情况下都是单例模式,除非修改beans.xml bean 属性:singleton="false" System.out.println(ic==ic2); ic.display(); } } Bean的创建: 1.工厂类创建:A.静态方法 B.new 工厂类 2.XmlBeanFactory:当getBean的时候创建bean实例 3.ClassPathXmlApplicationContext:当new这个对象后,就将资源中的bean读入到内存 程序目标: 一个类的属性的值通过一个工厂类的方法得到,这个工厂类有两个方法,一个是静态的,一个是成员方法,测试工厂类的使用 接口: package yuchen.factory; public interface Factory { public void display(); } 实现类: package yuchen.factory; public class FactoryImp implements Factory { public String name; public void display() { // TODO Auto-generated method stub System.out.println(name); } public String getName() { return name; } public void setName(String name) { this.name = name; } } 工厂类: package yuchen.factory; //工厂类:一个静态,一个动态 public class GetNameFactory { public static String createName(String s){ if(s.equals("yuchen")){ return "yuchen"; }else if(s.equals("liu")){ return "liu"; } return null; } public String newName(String s){ if(s.equals("yuchen")){ return "yuchen"; }else if(s.equals("liu")){ return "liu"; } return null; } } beans.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www./dtd/spring-beans.dtd" > <beans> <bean id="fac" class="yuchen.factory.FactoryImp"> <property name="name"> <ref bean="name"></ref> </property> </bean> <bean id="name1" class="yuchen.factory.GetNameFactory" factory- method="createName"> <constructor-arg> <value>yuchen</value> </constructor-arg> </bean> <bean id="getnamefactory" class="yuchen.factory.GetNameFactory" /> <bean id="name" factory-bean="getnamefactory" factory- method="newName"> <constructor-arg> <value>liu</value> </constructor-arg> </bean> </beans> Test: package yuchen.factory; /* * 知识点:使用工厂类的方法,给其他类的属性设置值 * 语法:beans.xml:静态方法: * <bean id="getnamefactory" class="yuchen.factory.GetNameFactory" /> * 成员方法: * <bean id="name" factory-bean="getnamefactory" factory-method="newName"> <constructor-arg> <value>liu</value> </constructor-arg> </bean> 使用该工厂的类: <property name="name"> <ref bean="name"></ref> </property> */ import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String [] args){ ClassPathXmlApplicationContext factory=new ClassPathXmlApplicationContext("yuchen/factory/beans.xml"); Factory f=(Factory) factory.getBean("fac"); f.display(); } } 继承属性:<bean Parent> 若干个bean,共有一个属性,使用继承 A类:a,b属性已经set或通过构造方法(属性a,属性b)设置好 B类:也有a,b同名属性 那么在beans.xml中使用<bean Parent>,B 继承 A就可以了,不用在xml中从新设置 抽象属性:<bean abstract="true|false"> 不能得到该类的实例 自动装配bean: 自动设置依赖关系:例如:A类持有B类的引用,引用属性名字和xml中的B类的id名字相同,那么会自动装配好 autowire="byName|byType|constructor" byName:属性—id 推荐 byType:找类名匹配,存在问题,当一个类多次出现会报错 constructor:根据构造方法类型匹配 依赖检查:dependency-check="all" 检查所有的set方法是否都被调用了,例如:如果有属性缺少set方法,那么会报异常 生命周期方法定制: 两种方式:1.使用bean属性 2.实现接口(不推荐,框架侵入性强:依赖API) 在构造方法和依赖注入set后调用init 综合实例(继承属性, 自动装配bean, 依赖检查,生命周期方法定制): A接口: package yuchen.beansp; public interface A { public void display(); } B接口: package yuchen.beansp; public interface B { public void dispaly(); } A实现类: package yuchen.beansp; public class AImp implements A { private String name; private int age; public AImp(String name) { super(); this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void display() { // TODO Auto-generated method stub System.out.println("Aimp: \n"); System.out.println(this.name+":"+this.age); } } B实现类: package yuchen.beansp; public class BImp implements B { private A a; private String name; private int age; public BImp(String name) { super(); this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public void dispaly() { // TODO Auto-generated method stub System.out.println("Bimp: \n"); System.out.println(this.name+":"+this.age); a.display(); } public void setA(A a) { this.a = a; } public void init(){ System.out.println("init...."); } public void destroy(){ System.out.println("destroy...."); } } beans.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www./dtd/spring-beans.dtd" > <beans> <bean id="a" class="yuchen.beansp.AImp"> <constructor-arg> <value>yuchen</value> </constructor-arg> <property name="age"> <value>24</value> </property> </bean> <bean id="b" class="yuchen.beansp.BImp" autowire="byName" parent="a" dependency-check="all" init-method="init" destroy-method="destroy" > </bean> </beans> Test: package yuchen.beansp; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub ClassPathXmlApplicationContext factory=new ClassPathXmlApplicationContext("yuchen/beansp/beans.xml"); B bb=(B) factory.getBean("b"); A aa=(A) factory.getBean("a"); aa.display(); bb.dispaly(); } } 获得当前bean的bean工厂对象和bean的实例名字(beans.xml中<bean id=””>): Bean类必须实现BeanFactoryAware接口 注意:不能使用依赖检查了,因为这个接口的方法不要求有set方法 Bean类必须实现BeanNameAware接口 注意:不能使用依赖检查了,因为这个接口的方法不要求有set方法 接口: package yuchen.factoryandname; public interface Bird { } 实现类: package yuchen.factoryandname; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanNameAware; public class CaiBird implements Bird ,BeanFactoryAware,BeanNameAware{ private String color; public String getColor() { return color; } public void setColor(String color) { this.color = color; } public void setBeanFactory(BeanFactory arg0) throws BeansException { // TODO Auto-generated method stub System.out.println("当前bean的bean工厂"); } public void setBeanName(String arg0) { // TODO Auto-generated method stub System.out.println(arg0+":"+this.color); } } xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www./dtd/spring-beans.dtd" > <beans> <bean id="bird" class="yuchen.factoryandname.CaiBird"> <property name="color"> <value>红色</value> </property> </bean> </beans> Test: package yuchen.factoryandname; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { // TODO Auto-generated method stub ClassPathXmlApplicationContext factory=new ClassPathXmlApplicationContext ("yuchen/factoryandname/beans.xml"); Bird bb=(Bird) factory.getBean("bird"); } } 以上内容为bean工厂部分 AppLicationContext 基本概念: 1.什么是ApplicationContext?有什么用? 2.和bean工厂的区别? 3.后续处理器 什么是ApplicationContext?有什么用? 是bean工厂的升级,增强了功能,例如国际化等 通过这个类可以得到bean对象 和bean工厂的区别? 功能更多 当实例这个对象的时候,该对象就会将资源中的bean实例存储到内存中 后续处理器: BeanPostProcessor 作用:可以在使用该实例前增加一些处理操作 程序目标: 接口: package yuchen.beanpostprocessor; public interface A { public void display(); } 实现类: package yuchen.beanpostprocessor; public class AImp implements A { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } public void display(){ System.out.println(this.name); } } 后续处理器: package yuchen.beanpostprocessor; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; public class UpperNamePostProcessor implements BeanPostProcessor{ public Object postProcessAfterInitialization(Object bean, String id) throws BeansException { // TODO Auto-generated method stub if(bean instanceof AImp){ AImp aimp=(AImp)bean; aimp.setName(aimp.getName().toUpperCase()); } return bean; } public Object postProcessBeforeInitialization(Object arg0, String arg1) throws BeansException { // TODO Auto-generated method stub return arg0; } } xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www./dtd/spring-beans.dtd" > <beans> <bean id="a" class="yuchen.beanpostprocessor.AImp"> <property name="name"> <value>yuchen</value> </property> </bean> <bean class="yuchen.beanpostprocessor.UpperNamePostProcessor"> </bean> </beans> Test: package yuchen.beanpostprocessor; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub ClassPathXmlApplicationContext factory=new ClassPathXmlApplicationContext("yuchen/beanpostprocessor/beans.xml"); A aa=(A) factory.getBean("a"); aa.display(); } |
|