1. Spring介绍
Spring的两大核心:控制反转(IOC)和面向切面(AOP);
2、控制反转(IOC)
控制反转和依赖注入(DI)同时使用,下面介绍为什么要使用这两个东东
当没有Spring时,我们使用Java编程,创建一个对象,可能需要下面这样:
package Test;
public class Learn01 {
private Say ss;
Learn01()
{
ss = new Say();
}
public void doo()
{
ss.say();
}
public static void main(String[] args)
{
Learn01 ll = new Learn01();
ll.doo();
}
}
class Say {
public void say()
{
System.out.println("Class Say... Func: say");
}
}
这里面最大的问题是,Learn01类对Say产生了依赖,因为在Learn01内部创建了对象,做单元测试时,不利于测试,无法构造多种Say对象;
为了解决Learn01对Say的依赖问题,代码可能整改成这个样子:
package Test;
public class Learn01 {
private Say ss;
public Say getSs() {
return ss;
}
public void setSs(Say ss) {
this.ss = ss;
}
public void doo()
{
ss.say();
}
public static void main(String[] args)
{
Learn01 ll = new Learn01();
Say ss = new Say("Hello World");
ll.setSs(ss);
ll.doo();
}
}
class Say {
private String message;
public Say(String msg)
{
message = msg;
}
public void say()
{
System.out.println("Class Say... Func: say " + message);
}
}
代码修改成这个样子,可以满足了 Learn01类和Say的依赖关系,但是Say类已经在硬编码中message已经写死为hello world,如果再想修改,就需要全篇代码去找,再全部修改过来;
于是,又有同学说,那我单独封装一个工厂类,用来创建这个对象:
package Test;
public class Learn01 {
private Say ss;
public Say getSs() {
return ss;
}
public void setSs(Say ss) {
this.ss = ss;
}
public void doo()
{
ss.say();
}
public static void main(String[] args)
{
Learn01 ll = new Learn01();
Say ss = (Say)Factory.create("Say");
ll.setSs(ss);
ll.doo();
}
}
class Say {
private String message;
public Say(String msg)
{
message = msg;
}
public void say()
{
System.out.println("Class Say... Func: say " + message);
}
}
class Factory
{
public static <E> E create(String clsName)
{
return (E)new Say("Hello World");
}
}
代码修改成这个样子以后,只要修改Factory中一处的内容即可,不需要全篇去修改代码了,解决了依赖问题。
理解了依赖的问题,下面说说Spring的控制反转,像Factory类一样,Learn01中想使用Say对象,本来应该自己创建,自己维护,现在变为Factory来创建和维护,自己作为一个使用者,控制权发生了反转,这就是控制反转;依赖注入可以理解为,Learn01依赖Say对象,我们可以通过Say注入到Learn01中,注入方式:
1. 构造函数注入
2. setter方法注入
3. Spring实现
1、下面spring库
https://repo.spring.io/release/org/springframework/spring/
2、在Eclipse中加入Spring所需要的库文件
3、在src目录下,创建beans.xml文件,实现setter方法注入:
<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-3.0.xsd">
<bean id="learn01" class="Test.Learn01">
<property name="ss" ref="say"/>
</bean>
<bean id="say" class="Test.Say">
<property name="message" value="Hello Axt0810"/>
</bean>
</beans>
说明:bean id用来唯一标识初始化的类,property是根据name的setter方法来进行注入,如果是参数,直接写value=xxx,如果是类,则用ref=xxx_id
package Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Learn01 {
private Say ss;
public void setSs(Say ss) {
this.ss = ss;
}
public void doo() {
ss.say();
}
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("beans.xml");
Learn01 ll = (Learn01)context.getBean("learn01");
ll.doo();
}
}
package Test;
public class Say {
private String message;
public void say(){
System.out.println("Class Say... Func: say " + message);
}
public void setMessage(String message) {
this.message = message;
}
}
main函数中,通过ClassPathXmlApplicationContext方法,读取xml中内容,通过getBean创建bean
4、构造方法注入
<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-3.0.xsd">
<bean id="learn01" class="Test.Learn01">
<property name="ss" ref="say"/>
</bean>
<bean id="say" class="Test.Say">
<constructor-arg value="Hello Axt"></constructor-arg>
</bean>
</beans>
package Test;
public class Say {
private String message;
public Say(String message) {
super();
this.message = message;
}
public void say(){
System.out.println("Class Say... Func: say " + message);
}
public void setMessage(String message) {
this.message = message;
}
}
5、集合类型注入
List:
<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-3.0.xsd">
<bean id="learn01" class="Test.Learn01">
<property name="ss" ref="say"/>
</bean>
<bean id="say" class="Test.Say">
<constructor-arg>
<list>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>USA</value>
</list>
</constructor-arg>
</bean>
<property name="addressSet">
<set>
<value>INDIA</value>
<value>Pakistan</value>
<value>USA</value>
<value>USA</value>
</set>
</property>
# key和value为任意类型
<map>
<entry key="1" value="INDIA"/>
<entry key="2" value="Pakistan"/>
<entry key="3" value="USA"/>
<entry key="4" value="USA"/>
</map>
# key和value为String
<property name="addressProp">
<props>
<prop key="one">INDIA</prop>
<prop key="two">Pakistan</prop>
<prop key="three">USA</prop>
<prop key="four">USA</prop>
</props>
</property>
# 当值为对象
<constructor-arg>
<list>
<ref bean="e1"/>
<ref bean="e2"/>
</list>
</constructor-arg>
</bean>
<bean id="e1" class="Test.Elem">
</bean>
<bean id="e2" class="Test.Elem">
</bean>
<constructor-arg>
<map>
<entry key-ref="e1" value-ref="e2" />
</map>
</constructor-arg>
</beans>