来自:http://blog.csdn.net/yuchen2008/archive/2007/05/27/1627226.aspx
Spring(二)
依赖注入的三种方式:
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.springframework.org/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.springframework.org/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.springframework.org/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.springframework.org/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.springframework.org/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.springframework.org/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();
}
}