在Spring中的控制反转——该技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。因此IOC另一个别名就是依赖注入
IOC:
对象由原来程序本身创建,变为程序接收对象。
程序员主要集中精力致力于业务实现
实现了service和dao的解耦,service和dao层分离了。
1,Ioc的无参构造方法创建bean
定义一个User.java类
package jym;
public class User {
private String name;
public User() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Beans.xml文件,在创建Spring中的beans.xml文件时候,必须包括<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"></beans>这几句配置文件。而且 在配置文件<propertyname=”name” value=”jym”/>这里面的name是User中setUser()函数的名字去掉set首字母转化成小写的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 name="user" class="jym.User">
<property name="name" value="jym"/>
</bean>
</beans>
Test.java 测试文件
package Test;
import jym.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test1 {
public static void main(String[] args) {
@SuppressWarnings("resource")
ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
User user=(User)context.getBean("user");
System.out.println("name="+user.getName());
}
}
2,有参构造方法创建bean
根据参数下标来进行赋值,index=""指的是构造方法的下标从零开始,使用参数名称和类型来进行创建bean。方法如下的xml文件。
User.java类
package jym;
public class User {
private String name;
public User(String name) {
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
beans.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 name="user" class="jym.User">
<!-- 使用index来调用构造方法来创建bena -->
<constructor-arg index="0" value="jym有餐"></constructor-arg>
<!-- 使用属性名称来创建bean -->
<constructor-arg name="name" value="jym有餐"></constructor-arg>
<!-- 使用属性类型来创建bean -->
<constructor-arg type="java.lang.String" value="jym有餐"></constructor-arg>
</bean>
</beans>
Test类如上所述;此处不再累述
3,工厂模式创建bean
(1)静态工厂模式
User.java
package jym;
public class User {
private String name;
public User() {
}
public User(String name) {
this.name=name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Factory.java 类
package fac;
import jym.User;
public class Factory {
public static User newInstance(String name) {
return new User(name);
}
}
Beans.xml 配置文件
在配置文件中factory-method="newInstance"这句话中,那个newInstance就是静态工厂里的方法名字
<?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="userFacSta" class="fac.Factory" factory-method="newInstance">
<constructor-arg name="name" value="jym"></constructor-arg>
</bean>
</beans>
Tset1.java
package Test;
import jym.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test1 {
public static void main(String[] args) {
@SuppressWarnings("resource")
ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
User user=(User)context.getBean("userFacSta");
System.out.println("name="+user.getName());
}
}
(2)动态工厂模式
动态工厂里就是把Factory.java中方法的static去掉,变成一个新的类就行。
dyFactory.java
package fac;
import jym.User;
public class dyFactory {
public User newInstance(String name) {
return new User(name);
}
}
beans.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 id="dyUserFacSta" class="fac.dyFactory"/>
<bean id="userFacSta" factory-bean="dyUserFacSta" factory-method="newInstance" >
<constructor-arg name="name" value="jymdy"></constructor-arg>
</bean>
</beans>
测试类,虽然这里变成了动态工厂模式,可是在获取bean的时候,依旧使用的是静态工厂的id
package Test;
import jym.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test1 {
public static void main(String[] args) {
@SuppressWarnings("resource")
ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
User user=(User)context.getBean("userFacSta");
System.out.println("name="+user.getName());
}
}
4,配置文件详解
1, alias设置bean的别名,可以设置多个别名
<alias name=”user” alias=”user1”
2,bean的配置
<!—id是bean的唯一标识符,如果没有配置id,name是默认的标识符,如果配置了id,又配置了name,那么name是别名,而且name可以设置多个别名,使用空格,逗号,分号
Class是bean的全限定名=包名+类名
如果不配置id和name,那么可以根据applicationContext.getBean(Class)获取对象
-->
<bean id=”user” name=”h1,h3,h4” class=” cn.nyist.jym.User ”>
<property name=”name” value=”jym”>
</bean>
注意在使用applicationContext.getBean(Class)获取对象的时候,示例:
Context.getBean(User.class);
3,团队协作使用import来实现
<import resource=”beans.xml”>
5,依赖注入
(1)依赖注入:
依赖:指的是bean对象的创建依赖容器。Bean对象依赖资源(例如,在动态的注入bean的时候,需要使用ref=”另外一个bean的name”)
注入:指bean的对象依赖资源由容器进行设置装配。
(2) spring注入,构造器注入,就是上面讲的有参无参注入
(3) spring注入—setting注入
要求注入的属性必须有set的方法。Set方法的方法名右set+属性首字母大写。如果属性是boolean,没有get方法,是is方法
注入的有,常亮注入,数组注入,列表注入,Map注入,set注入,null注入, Properties注入,P命名空间注入,c命名空间注入。注意在P和C命名空间的时候,需要在配置文件中加入下面两句话xmlns:p="http://www.springframework.org/schema/p" xmlns:c="http://www.springframework.org/schema/c"
在此配置文件中也说到了bean的作用域。
User.java类
package jym;
public class User {
private String name;
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public User() {
}
public User(String name,int age) {
this.name=name;
this.age=age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Student.java类
package jym;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class Student {
private String name;
private Address addr;
private String[] books;
private List<String> hobbies;
private Map<String,String> cards;
private Set<String> games;
private String wife;
private Properties info;
public Properties getInfo() {
return info;
}
public void setInfo(Properties info) {
this.info = info;
}
public String getWife() {
return wife;
}
public void setWife(String wife) {
this.wife = wife;
}
public Set<String> getGames() {
return games;
}
public void setGames(Set<String> games) {
this.games = games;
}
public Map<String, String> getCards() {
return cards;
}
public void setCards(Map<String, String> cards) {
this.cards = cards;
}
public List<String> getHobbies() {
return hobbies;
}
public void setHobbies(List<String> hobbies) {
this.hobbies = hobbies;
}
public String[] getBooks() {
return books;
}
public void setBooks(String[] books) {
this.books = books;
}
public Address getAddr() {
return addr;
}
public void setAddr(Address addr) {
this.addr = addr;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Beans.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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- bean注入 -->
<!-- scope="singleton,prototype,request,session"
singleto:单例,整个容器只有一个实例
prototype:原型,每次获取bean都产生一个新的对象
request:每次请求的时候获取一个对象
session:在会话的范围内是一个对象
global session :只在portlet下有用,表示是application这个不常用
-->
<bean name="addr1" class="jym.Address" >
<property name="addr" value="淮滨"/>
</bean>
<!-- 数组注入 -->
<bean name="stu" class="jym.Student">
<property name="name" value="jym"/>
<property name="addr" ref="addr1"/>
<property name="books">
<array>
<value>C++</value>
<value>Java</value>
</array>
</property>
<!-- 列表注入 -->
<property name="hobbies">
<list>
<value>羽毛球</value>
<value>台球</value>
</list>
</property>
<!-- Map注入 -->
<property name="cards">
<map>
<entry key="中国银行" value="324651613351"/>
<entry>
<key><value>建行</value></key>
<value>13216341023</value>
</entry>
</map>
</property>
<!-- set注入 -->
<property name="games">
<set>
<value>Lol</value>
<value>王者荣耀</value>
</set>
</property>
<!-- null注入 -->
<property name="wife">
<null></null>
</property>
<!-- Properties注入 -->
<property name="info">
<props>
<prop key="学号">1415925680</prop>
<prop key="姓名">简彦明</prop>
</props>
</property>
</bean>
<!-- P命名空间注入 属性依然要设置set方法,需要在头文件中添加:xmlns:p="http://www.springframework.org/schema/p"-->
<bean name="user" class="jym.User" p:name="jym" p:age="222"/>
<!-- c命名空间注入,需要在头文件中加入 xmlns:c="http://www.springframework.org/schema/c"-->
<!-- 要求有对应的参数的构造方法 -->
<bean name="user1" class="jym.User" c:name="jjj" c:age="3333"/>
</beans>
Test.java
package Test;
import java.util.List;
import jym.Student;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test2 {
public static void main(String[] args) {
//ApplicationContext context=ClassPathXml
@SuppressWarnings("resource")
ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
Student stu=(Student)context.getBean("stu");
System.out.println("name="+stu.getName()+" addr="+stu.getAddr().getAddr());
String[] books=stu.getBooks();
for(int i=0;i<books.length;i++) {
System.out.println("books["+i+"]="+books[i]);
}
List<String> hobbies=stu.getHobbies();
for (int i=0;i<hobbies.size();i++) {
System.out.println(hobbies.get(i));
}
System.out.println("cards ="+stu.getCards());
System.out.println("games ="+stu.getGames());
System.out.println("wife ="+stu.getWife());
System.out.println("info="+stu.getInfo());
System.out.println("--------------------------------------------");
User user=(User)context.getBean("user");
System.out.println("user name="+user.getName()+"user age="+user.getAge());
User user2=(User)context.getBean("user1");
System.out.println("user name="+user2.getName()+"user age="+user2.getAge()); }
}
输出结果:
name=jym addr=淮滨
books[0]=C++
books[1]=Java
羽毛球
台球
cards ={中国银行=324651613351,建行=13216341023}
games =[Lol, 王者荣耀]
wife =null
info={学号=1415925680,姓名=简彦明}
--------------------------------------------
user name=jymuser age=222
user name=jjjuser age=3333
6,自动装配
自动装配即使相互协作bean之间的关联关系。因此,如果可能的话,可以自动让Spring通过检查BeanFactory中的内容,来替我们指定bean的协作者(其他被依赖的bean)。由于autowire可以针对单个bean进行设置,因此可以让有些bean使用autowire,有些bean不采用。autowire的便之处在减少或者消除属性或构造器参数的设置,这样可以缩减配置文件配置文件
<bean id="mysqlDao" class="cn.sxt.dao.impl.UserDaoMySqlImpl"/>
<!-- autowire自动装配 简化spring配置
no不使用自动装配
byName 根据名称(set方法名来的)去查找相应的bean,如果有则装配上
byType 根据类型进行自动装配 不用管bean的id.但是同一种类型的bean只能有一个。建议慎用
constructor 当通过构造器 注入 实例化bean时 适用byType的方式 装配构造方法
-->
<bean id="service" class="cn.sxt.service.impl.UserServiceImpl" autowire="constructor"/>
在这里就是使用了自动装配。
Spring中的IOC大致就是这些东西了。