首页 > 代码库 > Spring

Spring

IOC:Inversion of Control 控制反转。(底层原理:反射)
所谓的控制反转,就是应用本身不负责依赖对象的创建及维护,依赖对象的创建及维护是由外部容器负责,这样控制权就用应用内部转移到了外部容器,这样做的目的是为了获得更好的扩展性和良好的可维护性。
DI:Dependency Injection 依赖注入 。(底层原理:内省)
所谓的依赖注入,就是在运行期,由外部容器动态地将依赖对象注入到组建中
以下是在bean.xml容器中,依赖注入的代码↓

<bean id="boy" class="com.dueeast.a_ioc.Boy" scope="prototype">

 

  </bean>

<bean id="girl" class="com.dueeast.a_ioc.Girl">

<property name="boy">

<ref bean="boy"/>

</property>

</bean>

       


前提是在com.dueeast.a_ioc.Girl 中,有对com.dueeast.a_ioc.Boy这个类的set方法↓

 


public class Girl {

Boy boy;

public void setBoy(Boy boy) {

this.boy boy;

}

public void kiss(){

boy.display();

System.out.println("kiss");

}

}


就可以这样使用了↓


 

public class App {

public static void main(String[] args) {

 

BeanFactory ac new XmlBeanFactory(new FileSystemResource("D:\\10.7MyEclipseSpace\\BlogTest\\src\\beans.xml"));

Girl girl (Girl) ac.getBean("girl");

girl.kiss();

}

}

以上是DI依赖注入的简单演示

-----------------------------------------------------------------------------------------------------------------------


在楼上代码中,下面这一句实例化了Spring的容器。

BeanFactory ac new XmlBeanFactory(new FileSystemResource("D:\\10.7MyEclipseSpace\\BlogTest\\src\\beans.xml"));


实例化Spring容器一共有四种方式↓

 


(1)加载一个spring容器

ApplicationContext ac new ClassPathXmlApplicationContext("容器全路径");

(2)加载多个spring容器

ApplicationContext ac new ClassPathXmlApplicationContext(new String[]{"容器全路径"});

(3)从外部文件系统加载容器

ApplicationContext ac new FileSystemXmlApplicationContext("容器在本地磁盘的绝对路径");

(4)使用BeanFactory的用法

BeanFactory ac new XmlBeanFactory(new FileSystemResource("容器在本地磁盘的绝对路径"));

 

项目中最常用是使用ApplicationContext和ClassPathXmlApplicationContext,一般不使用BeanFactory


ApplicationContext是对BeanFactory扩展,提供了更多功能

1、国际化处理

2、事件传递

3、Bean自动装配

4、各种不同应用层的Context实现


---------------------------------------------------------------------------------------------

创建对象的作用于模式:

单例模式singleton(默认值) 

如果是单例的话,将spring中bean元素节点的scope设置成singleton,加载spring容器的时候,就会加载对应的构造方法,此时构造方法只执行1次,表示单例

在spring容器中配置:lazy-init="false"(默认值);表示只要加载spring容器,此时就会立即加载构造对象的方法。

在spring容器中配置:lazy-init="true";表示只有调用对应对象的时候,才会初始化对应的构造方法。

如果在spring容器中的beans节点配置default-lazy-init="false"(默认值),对全局所有的bean都有效

多例模式prototype(整合由于struts2是多例,在spring容器创建Action对象的时候,将其设置多例)

如果是单例的话,将spring中bean元素节点的scope设置成prototype,加载spring容器的时候,不会加载执行对应对象的构造方法,此时只有调用对应对象的时候,才会执行对应的构造方法,执行多次,表示多例

多例中不会存在lazy-init属性,因为没有意义


 

request每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境(一个系统request.setAttribute () 

session同一个HTTP Session 共享一个Bean,不同Session使用不同Bean,仅适用于WebApplicationContext 环境(一个系统session.setAttribute())

global session一般用于Porlet应用环境,该作用域仅适用于WebApplicationContext 环境(多个系统共享一个session)

------------------------------------------------------------------------------------------

依赖注入详解


1、在类中的属性需要设置set方法(用以下javabean演示,set方法因过多而省略)

private Integer id;

 

private String name;

private Person person;

private List<Object> list;

private Object[] arrays;

private Set<Object> set;

private Map<String, Object> map;

private Properties properties;

//spring整合hibernate的时候,都可以在容器中使用Properties集合完成对hibernate的操作

private List<Object> listnull new ArrayList<Object>();


2、spring的容器中定义:

 

<bean id="person" class="h_setXml.Person" p:pid="30" p:pname="酸菜"></bean>

<bean id="userService" class="h_setXml.UserServiceImpl">

<!-- 1:配置bean的简单属性,基本数据类型和String。 -->

<property name="id" value=http://www.mamicode.com/"10"></property>

<property name="name" value=http://www.mamicode.com/"翠花"></property>

<!-- 

2:注入对象,引用其它bean(外部bean)

结论:项目开发时都会使用外部注入,因为由外部创建对象,容器中的其他对象都可以调用

如果是内部调用,只能在当前bean中才能使用

-->

<property name="person" ref="person"></property> 

<!-- 2:注入对象,内部bean 

<property name="person">

<bean class="cn.itcast.h_setXml.Person"></bean>

</property>-->

<!-- 3:测试p空间,为对象中的属性赋值 -->

<!-- 4:注入集合,A、装配List和数组(通用): -->

<property name="list">

<list>

<value>list001</value>

<value>list002</value>

<ref bean="person"/>

</list>

</property>

<property name="arrays">

<array>

<value>array001</value>

<value>array002</value>

<ref bean="person"/>

</array>

</property>

<!-- 4:注入集合, B、 装配set: -->

<property name="set">

<set>

<value>set001</value>

<value>set002</value>

<ref bean="person"/>

</set>

</property>

<!-- 4:注入集合,装配集合 C、 装配map: -->

<property name="map">

<map>

<entry key="key001">

<value>mapValue001</value>

</entry>

<entry key="key002">

<value>mapValue002</value>

</entry>

<entry key="key003">

<ref bean="person"/>

</entry>

</map>

</property>

<!-- 5:注入集合,D、装配Properties:值不可以是对象 -->

<property name="properties">

<props>

<prop key="prop001">propValue001</prop>

<prop key="prop002">propValue002</prop>

</props>

</property>

<!-- 6:设置空值 -->

<property name="listnull">

<null/>

</property>

</bean>

 


 


3、注入构造器并在类中使用构造器

 

在spring容器中定义:

<bean id="userService" class="i_constructorXml.UserServiceImpl">

<!-- 

constructor-arg:构造器函数注入的方式

  index:构造器方法中参数的位置,0表示第1个位置

  type:表示构造器方法中参数的类型,类型可以写成java的类型

  要求:

  1:按照位置注入:如果使用参数的位置注入,需要注入的值要符合构造方法参数的类型

  2:按照参数类型注入:根据构造函数参数的位置不同,可能会注入到不同的构造方法

<!-- 结论:当使用构造器函数的时候,可以使用即按照类型指定,同时也按照参数的位置指定 -->

<constructor-arg type="java.lang.String" index="1">

<value>1</value>

</constructor-arg>

<constructor-arg type="java.lang.String" index="0">

<value>翠花</value>

</constructor-arg>

</bean>

在类中使用构造函数,注入参数的值

public UserServiceImpl(String name,Integer id){

System.out.println("StringInteger");

this.id id;

this.name name;

}

 

public UserServiceImpl(Integer id,String name){

System.out.println("IntegerString");

this.id id;

this.name name;

}

 

public UserServiceImpl(String name,String education){

System.out.println("StringString");

this.name name;

this.education education;

}