Spring基础(IOC&DI)
2016-10-29 16:44
405 查看
Spring基础篇(IOC&DI)——导出自个人笔记
IOC控制反转:Inversion of Control
将设计好的类交给系统(由软件系统控制,运行前,我完全不知道用到哪些类)去控制,而不是你的类内部控制。
DI依赖注入:是控制反转的具体实现,在运行期由容器将依赖关系注入到组件之中。
优点:
DI注入方式:
1.Setter注入:通过属性的setXxx()方法进行注入 (bean、Array数组、List、Set、Map、Properties)
2.构造器注入:通过类的构造方法进行注入
3. 导入其他bean(引入外部Bean,内部引用Bean)
4.工厂方法创建bean
1&2. Setter注入(最常见) & Constructor注入
实体类:
package com.igeekhome.springreview.entity;
/**
* 用户实体类
*
* Created by student on 2016/10/28.
*/
public class User {
private int id;
private String name;
private String passwd;
private String sex;
public User() {
}
public User(int id, String name, String passwd, String sex) {
this.id = id;
this.name = name;
this.passwd = passwd;
this.sex = sex;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", passwd='" + passwd + '\'' +
", sex='" + sex + '\'' +
'}';
}
}
配置文件:
<?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">
<!--
spring容器来: 实例化bean,同时注入一个值
等同于
com.igeekhome.springreview.entity.User user = new com.igeekhome.springreview.entity.User();
user.setId(1001);
user.setName("zhengjinzhou");
user.setPasswd("123456");
user.setSex("男");
-->
<!--
bean的作用域:
singleton: 单例模式 (默认) 每次获取的都是相同的实例
static com.igeekhome.bean.HelloSpring hello = new com.igeekhome.bean.HelloSpring();
prototype: 原型模式 ,每次获取的都是不同的实例
-->
<bean id="user" class="com.igeekhome.springreview.entity.User" scope="prototype">
<!-- 反射 public void setId(int id) -->
<property name="id" value="1001"/>
<property name="name" value="zhengjinzhou"/>
<property name="passwd" value="123456"/>
<property name="sex" value="男"/>
</bean>
<!-- 构造器方法注入
默认情况是要按照实体类的构造器参数顺序类写constructor-arg
我们可以利用index 或 name 来打乱顺序
-->
<bean id="user1" class="com.igeekhome.springreview.entity.User" scope="prototype">
<constructor-arg index="1" name="name" value="feifei" />
<constructor-arg index="0" name="id" value="1002" />
<constructor-arg index="3" name="sex" value="女" />
<constructor-arg index="2" name="passwd" value="123456" />
</bean>
</beans>
测试:
使用Spring提供的测试套件
package com.igeekhome.springreview;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.igeekhome.springreview.entity.User;
/**
* 测试Setter注入和Constructor注入
* 利用Spring提供的测试套件
*
* @author zheng
* 2016年10月29日 上午10:37:08
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Review1Test {
@Resource(name="user")
private User user;
@Resource(name="user1")
private User user1;
@Test
public void testUser() {
System.out.println(user);
System.out.println(user1);
}
}
可以在配置文件中导入其他配置文件,也可以在需要的地方导入多个配置文件
在配置文件中导入其他配置文件
-------------------------------------------------------------------------
<!-- 导入外部的其他配置文件 -->
<!-- <import resource="classpath:applicationContext2.xml"/>
<import resource="classpath:applicationContext3.xml"/> -->
-------------------------------------------------------------------------
在需要的地方导入多个配置文件
-------------------------------------------------------------------------
//读取spring的配置文件
ApplicationContext ctx =
new ClassPathXmlApplicationContext("applicationContext.xml",
"applicationContext2.xml","applicationContext3.xml");
1&2. Array数组、List、Set、Map、Properties
实体:
//Array数组、List、Set
-----------------------------------------------------------------
package com.igeekhome.springreview.bean;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
/**
* 集合,数组注入
*
* @author zheng
* 2016年10月24日 上午11:22:02
*/
public class CollectionImport {
private String[] names;
private List<String> passwds;
private Set<String> hobbys;
//通过setter方法来注入
public void setNames(String[] names) {
this.names = names;
}
public void setPasswds(List<String> passwds) {
this.passwds = passwds;
}
public String[] getNames() {
return names;
}
public List<String> getPasswds() {
return passwds;
}
public Set<String> getHobbys() {
return hobbys;
}
public void setHobbys(Set<String> hobbys) {
this.hobbys = hobbys;
}
@Override
public String toString() {
return "CollectionImport [names=" + Arrays.toString(names) + ", passwds=" + passwds + ", hobbys=" + hobbys
+ "]";
}
}
---------------------------------------------------------------
//Map
---------------------------------------------------------------
package com.igeekhome.springreview.bean;
import java.util.Map;
/**
* Map注入
* 键值对
*
* @author zheng
* 2016年10月24日 上午11:35:06
*/
public class MapImport {
private Map<String, String> map;
public Map<String, String> getMap() {
return map;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void printMap(){
System.out.println("键:"+map.keySet());
System.out.println("值:"+map.values());
}
}
----------------------------------------------------------------
//Properties
------------------------------------------------------------------
package com.igeekhome.springreview.bean;
import java.util.Properties;
/**
* Properties注入:直属于Hashtable
* 类似于Map,
*
* @author zheng
* 2016年10月24日 上午11:45:24
*/
public class PropertiesImport {
private Properties properties;
public void setProperties(Properties properties) {
this.properties = properties;
}
public void printMap(){
System.out.println("键:"+properties.keySet());
System.out.println("值:"+properties.values());
}
}
配置:
<?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
array、 list、 set 通用的
-->
<bean id="collection" class="com.igeekhome.springreview.bean.CollectionImport">
<!-- 数组 -->
<property name="names">
<array>
<value>北京</value>
<value>上海</value>
<value>南京</value>
<value>南京</value>
</array>
</property>
<!-- List集合 -->
<property name="passwds">
<list>
<value>123</value>
<value>456</value>
<value>789</value>
<value>789</value>
</list>
</property>
<!-- Set集合(会去重) -->
<property name="hobbys">
<set>
<value>游泳</value>
<value>起飞</value>
<value>打牌</value>
<value>打牌</value>
</set>
</property>
</bean>
<!-- Map注入 -->
<bean id="map" class="com.igeekhome.springreview.bean.MapImport">
<property name="map">
<!-- 注入map -->
<map>
<entry key="one" value="1" />
<entry key="two" value="2" />
<entry key="three" value="3" />
<entry key="three" value="4" />
</map>
</property>
</bean>
<!-- Properties注入 -->
<bean id="properties" class="com.igeekhome.springreview.bean.PropertiesImport">
<property name="properties">
<props>
<prop key="prop1">prop1_value</prop>
<prop key="prop2">prop2_value</prop>
<prop key="prop3">prop3_value</prop>
<prop key="prop3">prop4_value</prop>
</props>
</property>
</bean>
</beans>
测试:
package com.igeekhome.springreview;
import java.util.Arrays;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.igeekhome.springreview.bean.CollectionImport;
import com.igeekhome.springreview.bean.MapImport;
import com.igeekhome.springreview.bean.PropertiesImport;
/**
* 测试数组,List集合,Set集合
* 利用Spring提供的测试套件
*
* @author zheng
* 2016年10月29日 上午10:37:08
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class Review2Test {
//注入待测试数据集合实体对象
@Resource(name="collection")
private CollectionImport collection;
//注入待测试数据Map实体对象
@Resource(name="map")
private MapImport map;
//注入待测试数据Properties实体对象
@Resource(name="properties")
private PropertiesImport properties;
@Test
public void testCollection() {
System.out.println("------------------测试数组与集合----------------------");
System.out.println("数组:"+Arrays.toString(collection.getNames()));
System.out.println("List集合:"+collection.getPasswds());
System.out.println("Set集合:"+collection.getHobbys());
System.out.println("Set集合,值唯一");
}
@Test
public void testMap(){
System.out.println("--------------------测试Map------------------------");
map.printMap();
System.out.println("键相等时,后者覆盖前者!");
}
@Test
public void testProperties(){
System.out.println("-------------------------测试Properties---------------------------");
properties.printMap();
System.out.println("键相等时,后者覆盖前者!");
}
}
3.导入其他bean(引入外部Bean,内部引用Bean)
原理:先在配置文件中配置注入一个UserDao的实现类,然后将这个实现类注入到UserService实现类中。
UserDaoImpl:
package com.igeekhome.dao;
import java.util.ArrayList;
import java.util.List;
import com.igeekhome.entity.User;
/**
* 用户Dao实现类
*
* @author zheng
* 2016年10月24日 下午2:43:36
*/
public class UserDaoImpl implements UserDao{
/** 查询所有用户 */
@Override
public List<User> findAllUsers() {
List<User> users = new ArrayList<>();
users.add(new User(1001, "郑锦洲1","123456"));
users.add(new User(1002, "郑锦洲2","123456"));
users.add(new User(1003, "郑锦洲3","123456"));
users.add(new User(1004, "郑锦洲4","123456"));
return users;
}
}
UserServiceImpl:
package com.igeekhome.service;
import java.util.List;
import com.igeekhome.dao.UserDao;
import com.igeekhome.entity.User;
/**
* 用户Service实现类
*
* @author zheng
* 2016年10月24日 下午2:49:38
*/
public class UserServiceImpl implements UserService {
//dao接口
private UserDao userDao;
//spring注入
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
/** 查询所有用户 */
@Override
public List<User> getAllUsers() {
return userDao.findAllUsers();
}
/** 根据用户编号查询用户 */
@Override
public User findUserById(int id) {
List<User> users = userDao.findAllUsers();
User u = null;
for(User user : users){
if(user.getId() == id){
u = user;
}
}
return u;
}
}
配置:
<?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">
<!-- dao -->
<bean id="userDao" class="com.igeekhome.dao.UserDaoImpl"/>
<!-- 业务类
引入外部的Bean -->
<bean id="userService" class="com.igeekhome.service.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
<!-- 内部引入Bean -->
<bean id="userService1" class="com.igeekhome.service.UserServiceImpl">
<property name="userDao">
<bean class="com.igeekhome.dao.UserDaoImpl"/>
</property>
</bean>
</beans>
测试:
package com.igeekhome.loadbean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.igeekhome.entity.User;
import com.igeekhome.service.UserService;
/**
* @author zheng
* 2016年10月24日 下午3:05:01
*/
public class LoadBean1Test {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext6.xml");
//UserService us = (UserService)ctx.getBean("userService");
UserService us = (UserService)ctx.getBean("userService1");
User user = us.findUserById(1002);
System.out.println(user);
}
}
4.工厂方法创建bean
构建工厂:
package com.igeekhome.springreview.factory;
import com.igeekhome.springreview.entity.User;
/**
* 用户工厂类
* 静态工厂方法
* 实例工厂方法
*
* @author zheng
* 2016年10月29日 上午11:37:30
*/
public class UserFactory {
/**
* 静态工厂方法
* @return
*/
public static User createUserByStaticFactory(){
return new User(1001, "静态工厂生产", "123456", "男");
}
/**
* 实例工厂方法
* @return
*/
public User createUserByFactory(){
return new User(1002, "实例工厂生产", "feifeifei", "男");
}
}
配置:
<?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="user1" class="com.igeekhome.springreview.factory.UserFactory"
factory-method="createUserByStaticFactory" />
<!-- 实例工厂方法 -->
<!-- 先有一个对应的工厂Bean -->
<bean id="factory" class="com.igeekhome.springreview.factory.UserFactory" />
<!-- 根据这个工厂bean 生成对应其生产的东西 -->
<bean id="user2" factory-bean="factory" factory-method="createUserByFactory" />
</beans>
测试:
package com.igeekhome.springreview;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.igeekhome.springreview.entity.User;
/**
* 测试工厂方法来构建Bean
* 利用Spring提供的测试套件
* 静态工厂
* 实例工厂
*
* @author zheng
* 2016年10月29日 上午10:37:08
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext3.xml")
public class Review3Test {
//注入由静态工厂构建的Bean
@Resource(name="user1")
private User user1;
//注入由实例工厂构建的Bean
@Resource(name="user2")
private User user2;
@Test
public void testStaticFactory() {
System.out.println("静态工厂构建:"+user1);
}
@Test
public void testFactory(){
System.out.println("实例工厂构建:"+user2);
}
}
小扩展:
Bean生命周期方法:
<?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的生命周期方法
init-method
destroy-method
-->
<bean id="user" class="com.igeekhome.entity.User"
init-method="init" destroy-method="destory" />
</beans>
Bean的作用域:
singleton; prototype; request; session
Bean的装配:
自动装配(使用配置文件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">
<!-- 实例化UserDaoImpl 的 Bean -->
<bean id="userDao" class="com.igeekhome.dao.UserDaoImpl" />
<bean id="userDao1" class="com.igeekhome.dao.UserDaoImpl" />
<!--
自动装配
类型
- default
- no
- byName 所需依赖的属性名称和我已经设置装配的Bean的id字段匹配
- byType 存在问题,如果当前项目的存在多个对应类型的实例Bean时,比如上面的userDao和userDao1,会存在问题,无法确定使用哪一个。
- constructor
-->
<!-- 出现问题了!!!
<bean id="userService" class="com.igeekhome.service.UserServiceImpl" autowire="byType" />
-->
<!-- 实例化UserServiceImpl 的Bean 并为其属性进行【自动装配】 -->
<bean id="userService1" class="com.igeekhome.service.UserServiceImpl" autowire="byName" />
</beans>
测试:
package com.igeekhome.loadbean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.igeekhome.entity.User;
import com.igeekhome.service.UserService;
/**
* 自动装配测试
* @author zheng
* 2016年10月24日 下午3:05:01
*/
public class LoadBean4Test {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext9.xml");
//配置了 autowire="byType"
//UserService userService = (UserService)ctx.getBean("userService");
//配置了 autowire="byName"
UserService userService = (UserService)ctx.getBean("userService1");
User user = userService.findUserById(1002);
System.out.println(user);
}
}
重点:
注解的使用:
注解实现手动装配
注解实现自动装配
配置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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- 开启自动扫描 -->
<context:component-scan base-package="com.igeekhome" />
</beans>
组件注解标签(每个被标注的类,都是一个组件,会被扫描到)
@Service : 用于标注业务层组件
@Controller :用于标注控制层组件(如SpringMVC中的控制器)
@Repository :用于标注数据访问组件,即DAO组件
@Component :泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注
装配注解:
Autowired : 可以标注在属性和setter方法上。
Autowired注解默认按类型进行装配(byType)
获取该注解标注的属性或setter方法参数的类型
以该类型为条件到Spring的容器(applicationContext.xml)中去查找bean的id节点的类型,找到以后,获取该节点对应的对象,利用反射直接为属性赋值。
Qualifier("name") :该注解以名字为条件查找依赖对象,如果不存在该名称的对象,抛出异常!
实例:
Resource:可以标注在属性和setter方法上
如果没有直达name属性
获取该注解的属性名称,以该名称为条件到spring容器(applicationContext.xml)中去查找bean的id节点的值相等节点,找到以后,获取该节点对应的对象,利用反射直接赋值。如果没有找到,@Resource注解会再次按类型装配。
如果指定name属性 只能按名称装配
获取该注解标注的属性名称,如果不存在该名称,抛出异常.
Value:装配值
实例:
Required :适用于bean属性的setter方法
指示受影响的bean属性必须在配置时被填充在XML配置文件中,否则容器将抛出BeanInitalizationException异常。
实例:
IOC控制反转:Inversion of Control
将设计好的类交给系统(由软件系统控制,运行前,我完全不知道用到哪些类)去控制,而不是你的类内部控制。
DI依赖注入:是控制反转的具体实现,在运行期由容器将依赖关系注入到组件之中。
优点:
DI注入方式:
1.Setter注入:通过属性的setXxx()方法进行注入 (bean、Array数组、List、Set、Map、Properties)
2.构造器注入:通过类的构造方法进行注入
3. 导入其他bean(引入外部Bean,内部引用Bean)
4.工厂方法创建bean
1&2. Setter注入(最常见) & Constructor注入
实体类:
package com.igeekhome.springreview.entity;
/**
* 用户实体类
*
* Created by student on 2016/10/28.
*/
public class User {
private int id;
private String name;
private String passwd;
private String sex;
public User() {
}
public User(int id, String name, String passwd, String sex) {
this.id = id;
this.name = name;
this.passwd = passwd;
this.sex = sex;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", passwd='" + passwd + '\'' +
", sex='" + sex + '\'' +
'}';
}
}
配置文件:
<?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">
<!--
spring容器来: 实例化bean,同时注入一个值
等同于
com.igeekhome.springreview.entity.User user = new com.igeekhome.springreview.entity.User();
user.setId(1001);
user.setName("zhengjinzhou");
user.setPasswd("123456");
user.setSex("男");
-->
<!--
bean的作用域:
singleton: 单例模式 (默认) 每次获取的都是相同的实例
static com.igeekhome.bean.HelloSpring hello = new com.igeekhome.bean.HelloSpring();
prototype: 原型模式 ,每次获取的都是不同的实例
-->
<bean id="user" class="com.igeekhome.springreview.entity.User" scope="prototype">
<!-- 反射 public void setId(int id) -->
<property name="id" value="1001"/>
<property name="name" value="zhengjinzhou"/>
<property name="passwd" value="123456"/>
<property name="sex" value="男"/>
</bean>
<!-- 构造器方法注入
默认情况是要按照实体类的构造器参数顺序类写constructor-arg
我们可以利用index 或 name 来打乱顺序
-->
<bean id="user1" class="com.igeekhome.springreview.entity.User" scope="prototype">
<constructor-arg index="1" name="name" value="feifei" />
<constructor-arg index="0" name="id" value="1002" />
<constructor-arg index="3" name="sex" value="女" />
<constructor-arg index="2" name="passwd" value="123456" />
</bean>
</beans>
测试:
使用Spring提供的测试套件
package com.igeekhome.springreview;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.igeekhome.springreview.entity.User;
/**
* 测试Setter注入和Constructor注入
* 利用Spring提供的测试套件
*
* @author zheng
* 2016年10月29日 上午10:37:08
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Review1Test {
@Resource(name="user")
private User user;
@Resource(name="user1")
private User user1;
@Test
public void testUser() {
System.out.println(user);
System.out.println(user1);
}
}
可以在配置文件中导入其他配置文件,也可以在需要的地方导入多个配置文件
在配置文件中导入其他配置文件
-------------------------------------------------------------------------
<!-- 导入外部的其他配置文件 -->
<!-- <import resource="classpath:applicationContext2.xml"/>
<import resource="classpath:applicationContext3.xml"/> -->
-------------------------------------------------------------------------
在需要的地方导入多个配置文件
-------------------------------------------------------------------------
//读取spring的配置文件
ApplicationContext ctx =
new ClassPathXmlApplicationContext("applicationContext.xml",
"applicationContext2.xml","applicationContext3.xml");
1&2. Array数组、List、Set、Map、Properties
实体:
//Array数组、List、Set
-----------------------------------------------------------------
package com.igeekhome.springreview.bean;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
/**
* 集合,数组注入
*
* @author zheng
* 2016年10月24日 上午11:22:02
*/
public class CollectionImport {
private String[] names;
private List<String> passwds;
private Set<String> hobbys;
//通过setter方法来注入
public void setNames(String[] names) {
this.names = names;
}
public void setPasswds(List<String> passwds) {
this.passwds = passwds;
}
public String[] getNames() {
return names;
}
public List<String> getPasswds() {
return passwds;
}
public Set<String> getHobbys() {
return hobbys;
}
public void setHobbys(Set<String> hobbys) {
this.hobbys = hobbys;
}
@Override
public String toString() {
return "CollectionImport [names=" + Arrays.toString(names) + ", passwds=" + passwds + ", hobbys=" + hobbys
+ "]";
}
}
---------------------------------------------------------------
//Map
---------------------------------------------------------------
package com.igeekhome.springreview.bean;
import java.util.Map;
/**
* Map注入
* 键值对
*
* @author zheng
* 2016年10月24日 上午11:35:06
*/
public class MapImport {
private Map<String, String> map;
public Map<String, String> getMap() {
return map;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public void printMap(){
System.out.println("键:"+map.keySet());
System.out.println("值:"+map.values());
}
}
----------------------------------------------------------------
//Properties
------------------------------------------------------------------
package com.igeekhome.springreview.bean;
import java.util.Properties;
/**
* Properties注入:直属于Hashtable
* 类似于Map,
*
* @author zheng
* 2016年10月24日 上午11:45:24
*/
public class PropertiesImport {
private Properties properties;
public void setProperties(Properties properties) {
this.properties = properties;
}
public void printMap(){
System.out.println("键:"+properties.keySet());
System.out.println("值:"+properties.values());
}
}
配置:
<?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
array、 list、 set 通用的
-->
<bean id="collection" class="com.igeekhome.springreview.bean.CollectionImport">
<!-- 数组 -->
<property name="names">
<array>
<value>北京</value>
<value>上海</value>
<value>南京</value>
<value>南京</value>
</array>
</property>
<!-- List集合 -->
<property name="passwds">
<list>
<value>123</value>
<value>456</value>
<value>789</value>
<value>789</value>
</list>
</property>
<!-- Set集合(会去重) -->
<property name="hobbys">
<set>
<value>游泳</value>
<value>起飞</value>
<value>打牌</value>
<value>打牌</value>
</set>
</property>
</bean>
<!-- Map注入 -->
<bean id="map" class="com.igeekhome.springreview.bean.MapImport">
<property name="map">
<!-- 注入map -->
<map>
<entry key="one" value="1" />
<entry key="two" value="2" />
<entry key="three" value="3" />
<entry key="three" value="4" />
</map>
</property>
</bean>
<!-- Properties注入 -->
<bean id="properties" class="com.igeekhome.springreview.bean.PropertiesImport">
<property name="properties">
<props>
<prop key="prop1">prop1_value</prop>
<prop key="prop2">prop2_value</prop>
<prop key="prop3">prop3_value</prop>
<prop key="prop3">prop4_value</prop>
</props>
</property>
</bean>
</beans>
测试:
package com.igeekhome.springreview;
import java.util.Arrays;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.igeekhome.springreview.bean.CollectionImport;
import com.igeekhome.springreview.bean.MapImport;
import com.igeekhome.springreview.bean.PropertiesImport;
/**
* 测试数组,List集合,Set集合
* 利用Spring提供的测试套件
*
* @author zheng
* 2016年10月29日 上午10:37:08
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class Review2Test {
//注入待测试数据集合实体对象
@Resource(name="collection")
private CollectionImport collection;
//注入待测试数据Map实体对象
@Resource(name="map")
private MapImport map;
//注入待测试数据Properties实体对象
@Resource(name="properties")
private PropertiesImport properties;
@Test
public void testCollection() {
System.out.println("------------------测试数组与集合----------------------");
System.out.println("数组:"+Arrays.toString(collection.getNames()));
System.out.println("List集合:"+collection.getPasswds());
System.out.println("Set集合:"+collection.getHobbys());
System.out.println("Set集合,值唯一");
}
@Test
public void testMap(){
System.out.println("--------------------测试Map------------------------");
map.printMap();
System.out.println("键相等时,后者覆盖前者!");
}
@Test
public void testProperties(){
System.out.println("-------------------------测试Properties---------------------------");
properties.printMap();
System.out.println("键相等时,后者覆盖前者!");
}
}
3.导入其他bean(引入外部Bean,内部引用Bean)
原理:先在配置文件中配置注入一个UserDao的实现类,然后将这个实现类注入到UserService实现类中。
UserDaoImpl:
package com.igeekhome.dao;
import java.util.ArrayList;
import java.util.List;
import com.igeekhome.entity.User;
/**
* 用户Dao实现类
*
* @author zheng
* 2016年10月24日 下午2:43:36
*/
public class UserDaoImpl implements UserDao{
/** 查询所有用户 */
@Override
public List<User> findAllUsers() {
List<User> users = new ArrayList<>();
users.add(new User(1001, "郑锦洲1","123456"));
users.add(new User(1002, "郑锦洲2","123456"));
users.add(new User(1003, "郑锦洲3","123456"));
users.add(new User(1004, "郑锦洲4","123456"));
return users;
}
}
UserServiceImpl:
package com.igeekhome.service;
import java.util.List;
import com.igeekhome.dao.UserDao;
import com.igeekhome.entity.User;
/**
* 用户Service实现类
*
* @author zheng
* 2016年10月24日 下午2:49:38
*/
public class UserServiceImpl implements UserService {
//dao接口
private UserDao userDao;
//spring注入
public void setUserDao(UserDao userDao){
this.userDao = userDao;
}
/** 查询所有用户 */
@Override
public List<User> getAllUsers() {
return userDao.findAllUsers();
}
/** 根据用户编号查询用户 */
@Override
public User findUserById(int id) {
List<User> users = userDao.findAllUsers();
User u = null;
for(User user : users){
if(user.getId() == id){
u = user;
}
}
return u;
}
}
配置:
<?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">
<!-- dao -->
<bean id="userDao" class="com.igeekhome.dao.UserDaoImpl"/>
<!-- 业务类
引入外部的Bean -->
<bean id="userService" class="com.igeekhome.service.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
<!-- 内部引入Bean -->
<bean id="userService1" class="com.igeekhome.service.UserServiceImpl">
<property name="userDao">
<bean class="com.igeekhome.dao.UserDaoImpl"/>
</property>
</bean>
</beans>
测试:
package com.igeekhome.loadbean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.igeekhome.entity.User;
import com.igeekhome.service.UserService;
/**
* @author zheng
* 2016年10月24日 下午3:05:01
*/
public class LoadBean1Test {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext6.xml");
//UserService us = (UserService)ctx.getBean("userService");
UserService us = (UserService)ctx.getBean("userService1");
User user = us.findUserById(1002);
System.out.println(user);
}
}
4.工厂方法创建bean
构建工厂:
package com.igeekhome.springreview.factory;
import com.igeekhome.springreview.entity.User;
/**
* 用户工厂类
* 静态工厂方法
* 实例工厂方法
*
* @author zheng
* 2016年10月29日 上午11:37:30
*/
public class UserFactory {
/**
* 静态工厂方法
* @return
*/
public static User createUserByStaticFactory(){
return new User(1001, "静态工厂生产", "123456", "男");
}
/**
* 实例工厂方法
* @return
*/
public User createUserByFactory(){
return new User(1002, "实例工厂生产", "feifeifei", "男");
}
}
配置:
<?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="user1" class="com.igeekhome.springreview.factory.UserFactory"
factory-method="createUserByStaticFactory" />
<!-- 实例工厂方法 -->
<!-- 先有一个对应的工厂Bean -->
<bean id="factory" class="com.igeekhome.springreview.factory.UserFactory" />
<!-- 根据这个工厂bean 生成对应其生产的东西 -->
<bean id="user2" factory-bean="factory" factory-method="createUserByFactory" />
</beans>
测试:
package com.igeekhome.springreview;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.igeekhome.springreview.entity.User;
/**
* 测试工厂方法来构建Bean
* 利用Spring提供的测试套件
* 静态工厂
* 实例工厂
*
* @author zheng
* 2016年10月29日 上午10:37:08
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext3.xml")
public class Review3Test {
//注入由静态工厂构建的Bean
@Resource(name="user1")
private User user1;
//注入由实例工厂构建的Bean
@Resource(name="user2")
private User user2;
@Test
public void testStaticFactory() {
System.out.println("静态工厂构建:"+user1);
}
@Test
public void testFactory(){
System.out.println("实例工厂构建:"+user2);
}
}
小扩展:
Bean生命周期方法:
<?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的生命周期方法
init-method
destroy-method
-->
<bean id="user" class="com.igeekhome.entity.User"
init-method="init" destroy-method="destory" />
</beans>
Bean的作用域:
singleton; prototype; request; session
Bean的装配:
自动装配(使用配置文件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">
<!-- 实例化UserDaoImpl 的 Bean -->
<bean id="userDao" class="com.igeekhome.dao.UserDaoImpl" />
<bean id="userDao1" class="com.igeekhome.dao.UserDaoImpl" />
<!--
自动装配
类型
- default
- no
- byName 所需依赖的属性名称和我已经设置装配的Bean的id字段匹配
- byType 存在问题,如果当前项目的存在多个对应类型的实例Bean时,比如上面的userDao和userDao1,会存在问题,无法确定使用哪一个。
- constructor
-->
<!-- 出现问题了!!!
<bean id="userService" class="com.igeekhome.service.UserServiceImpl" autowire="byType" />
-->
<!-- 实例化UserServiceImpl 的Bean 并为其属性进行【自动装配】 -->
<bean id="userService1" class="com.igeekhome.service.UserServiceImpl" autowire="byName" />
</beans>
测试:
package com.igeekhome.loadbean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.igeekhome.entity.User;
import com.igeekhome.service.UserService;
/**
* 自动装配测试
* @author zheng
* 2016年10月24日 下午3:05:01
*/
public class LoadBean4Test {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext9.xml");
//配置了 autowire="byType"
//UserService userService = (UserService)ctx.getBean("userService");
//配置了 autowire="byName"
UserService userService = (UserService)ctx.getBean("userService1");
User user = userService.findUserById(1002);
System.out.println(user);
}
}
重点:
注解的使用:
注解实现手动装配
注解实现自动装配
配置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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- 开启自动扫描 -->
<context:component-scan base-package="com.igeekhome" />
</beans>
组件注解标签(每个被标注的类,都是一个组件,会被扫描到)
@Service : 用于标注业务层组件
@Controller :用于标注控制层组件(如SpringMVC中的控制器)
@Repository :用于标注数据访问组件,即DAO组件
@Component :泛指组件,当组件不好归类的时候,我们可以使用这个注解进行标注
装配注解:
Autowired : 可以标注在属性和setter方法上。
Autowired注解默认按类型进行装配(byType)
获取该注解标注的属性或setter方法参数的类型
以该类型为条件到Spring的容器(applicationContext.xml)中去查找bean的id节点的类型,找到以后,获取该节点对应的对象,利用反射直接为属性赋值。
Qualifier("name") :该注解以名字为条件查找依赖对象,如果不存在该名称的对象,抛出异常!
实例:
Resource:可以标注在属性和setter方法上
如果没有直达name属性
获取该注解的属性名称,以该名称为条件到spring容器(applicationContext.xml)中去查找bean的id节点的值相等节点,找到以后,获取该节点对应的对象,利用反射直接赋值。如果没有找到,@Resource注解会再次按类型装配。
如果指定name属性 只能按名称装配
获取该注解标注的属性名称,如果不存在该名称,抛出异常.
Value:装配值
实例:
Required :适用于bean属性的setter方法
指示受影响的bean属性必须在配置时被填充在XML配置文件中,否则容器将抛出BeanInitalizationException异常。
实例:
相关文章推荐
- Spring学习笔记之基础、IOC、DI(1)
- Spring_IOC&DI概述
- Spring基础-1-IOC与DI
- (spring-第7回【IoC基础篇】)BeanDefinition的载入与解析&&spring.schemas、spring.handlers的使用
- Spring4 之 IOC & DI
- Spring-3,IOC&DI的简单理解
- 3、Spring IOC&DI使用
- spring学习总结(五):IOC & DI 配置 Bean 之自动装配及bean之间的关系
- Spring基础[IOC/DI、AOP]
- Spring 基础概念——DI、IOC(一)
- (二)Spring的IOC&DI概述
- spring学习总结(三):IOC & DI 配置 Bean 之配置形式及依赖注入方式
- spring学习总结(四):IOC & DI 配置 Bean 之注入属性细节
- spring学习总结(七):IOC & DI 配置Bean之bean的生命周期及bean的配置方式
- Spring4.3x教程之一IOC&DI
- spring_1-4,IOC&DI概述_配置 Bean_属性配置细节
- spring学习总结(二):IOC & DI 概述及 IOC 容器
- Spring学习第二天:Spring_IOC&DI概述
- Spring基础(一)——AOP&IoC
- Spring学习笔记之基础、IOC、DI(1)