Spring框架学习笔记1-----IoC、DI

目录

1、Spring框架概述

2、IOC 

2.1、导入jar包

2.2、目标类

2.3、配置文件

2.4、测试

3、DI

3.1、依赖注入

3.2、配置信息

3.3、举例说明 

4、核心API 、

4.1、BeanFactory:

4.2、ApplicationContext:

5、装配Bean基于XML

5.1、实例化方式(三种)

5.1.1、默认构造

5.1.2、静态工厂及其测试:

5.1.3、实例工厂及其测试

5.2、Bean的种类

5.2.1、普通Bean:

5.2.2、FactoryBean:

5.2.3、BeanFactory 和FactoryBean对比:

5.3、作用域

5.3.1、作用域:

5.3.2、取值:

5.3.3、配置信息:

5.3.4、测试 

4、Bean的生命周期

5.4.1、初始化和销毁及其测试

5.4.2、BeanPOSTProcessor后处理Bean

5、属性依赖注入

5.5.1、构造方法(之后再补充)

5.5.2、setter方法

5.5.3、P命令空间[了解]

5.5.4、SpEL(了解)

6、集合注入(Array、List、Set、Map、Properties)

6、装配Bean基于注解

6.1、什么是注解

6.2、注解分类

6.3、生命周期

6.4、作用域

7、注解和xml混合使用


 

1、Spring框架概述

2、IOC 

2.1、导入jar包

四个核心(beans、core、context、expression)和一个依赖(commons.logging)

2.2、目标类

在之前的学习中,通常通过new实例化对象,学习spring框架后,将由spring创建对象的实例,即IoC(Inverse of control,控制反转)

创建UserService接口和其实现类

public interface UserService {
	public void addUser();
}
public class UserServiceImpl implements UserService{
	@Override
	public void addUser() {
		// TODO 自动生成的方法存根
		System.out.println("test of ioc");
	}
}

2.3、配置文件

<?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 definitions here
	<bean>这个标签配置的是我们需要创建的对象
	     id:用于之后从Spring容器获得实例时使用
		 class:需要创建实例时的全限定名
	-->
	<bean id="UserServiceId" class = "test_ioc.UserServiceImpl" ></bean>
</beans>

2.4、测试

public class TestIoC {
	@Test
	public void demo01() {
		//之前学习的是以下方式new实例对象
		UserService userService = new UserServiceImpl();
		userService.addUser();
	}
	
	@Test
	public void demo02() {
		/*
		 * 从Spring容器中获得实例对象
		 * 1、获取容器
		 * 2、获得内容
		 */
		//1、获取容器
		String xmlPath = "applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		//2、获取内容:不需要自己new 都是从spring容器中获得
		
		UserService userService = (UserService) applicationContext.getBean("UserServiceId");
		userService.addUser();
	}

}

结果如下:

3、DI

3.1、依赖注入

依赖:一个对象需要使用到另一个对象注入:通过setter方法进行另一个对象实例设置

class B{
    private A a;
    setter方法;
};//B中有一个成员变量a,称为B依赖于A 

3.2、配置信息

<bean id = "" class = "">
    <property name = "" ref = ""></property>
</bean>
<property>标签:用于进行属性注入
name :bean的属性名,通过setter方法获得
ref:另一个bean的id值的引用

 

3.3、举例说明 

1、目标类:dao、service

  • 创建BookService接口和实现类
  • 创建BookDao接口和实现类
public interface BookDao {
	public void addBook();
}

public class BookDaoImpl implements BookDao {
	@Override
	public void addBook() {
		// TODO 自动生成的方法存根
		System.out.println("di add book");
	}
}

public interface BookService {
	public void addBook();
}

public class BookServiceImpl implements BookService {
	//方式一:接口+实现类
	//private BookDao bookDao = new BookDaoImpl();
	//方式二:接口+setter
	private BookDao bookDao;
	//setter方法
	public void setBookDao(BookDao bookDao) {
		this.bookDao = bookDao;
	}
	@Override
	public void addBook() {
		// TODO 自动生成的方法存根
		this.bookDao.addBook();
	}
}

2、配置文件

  • 将dao和service配置到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 definitions here
	模拟spring的执行过程
	创建service实例:BookService bookService = new BookServiceImpl();   IoC   (<bean>)
	创建dao实例:BookDao bookDao = new BookDaoImpl();   IoC   (<bean>)
	将dao设置给service:bookService.setBookDao(bookDao);   DI   (<property>)
	<property>标签:用于进行属性注入
		name :bean的属性名,通过setter方法获得
			bookDao
		ref:另一个bean的id值的引用
			bookDaoId
	-->
	<!-- 创建service-->
	<bean id="bookServiceId" class="test_di.BookServiceImpl">
		<property name="bookDao" ref="bookDaoId"></property>
	</bean>
	<!-- 创建dao-->
	<bean id="bookDaoId" class = "test_di.BookDaoImpl"></bean>
	
</beans>

3、测试

public class TestDi {
	@Test
	public void demo() {
		//从spring容器中获得
		String xmlPath = "test_di/applicationContext.xml";
		ApplicationContext applicationcontext= new ClassPathXmlApplicationContext(xmlPath);
		BookService bookService = (BookService) applicationcontext.getBean("bookServiceId");
		bookService.addBook();
	}
}

 

4、核心API 、

4.1、BeanFactory:

工厂,用于生成任意bean。采取延迟加载,第一次getBean时会初始化Bean

4.2、ApplicationContext:

是BeanFactory的子接口,功能更加强大(国际化处理、事件传递、Bean自动装配、各种不同应用层的Context实现)。当配置文件被加载就进行了对象的实例化

  1. ClassPathXmlApplicationContext:用于加载classpath(类路径,src)下的xml
  2. FileSystemXmlApplicationContext:用于加载指定盘符下的xml

5、装配Bean基于XML

5.1、实例化方式(三种)

5.1.1、默认构造

<bean id="" class=""></bean>;
              --->必须提供默认构造(就是没有写构造方法时系统默认的无参构造)

5.1.2、静态工厂及其测试:

  1. 常用于Spring整合其他框架(工具)
  2. 用于生产实例对象,所有的方法必须是static

配置信息

<bean id="" class="工厂的全限定类名" factory-method="静态方法"></bean>

测试 

 之前的学习的静态工厂:

//People接口
public interface People {
	public void newPeople();
}
//People接口的实现类
public class PeopleImpl implements People {
	@Override
	public void newPeople() {
		// TODO 自动生成的方法存根
		System.out.println("create a people");
	}
}

//静态工厂
public class MyBeanFactory {

	public static People createPeople() {
		return new PeopleImpl();
	}

}

//静态工厂测试
public class TestStaticFactory {
	@Test
	public void demo01() {
		People people = MyBeanFactory.createPeople();
		people.newPeople();
	}
}

 学习Spring后:

//测试类如下
public class TestStaticFactory {
	@Test
	public void demo02() {
		//Spring工厂
		String xmlPath = "test_b_inject_static_factory/applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		People people = applicationContext.getBean("People",People.class);
		people.newPeople();
	}
}

 spring配置信息:(主要是写配置信息)

<?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 definitions here-->
    <!--  将静态工厂创建的实例教育spring 
    class:确定静态工厂全限定名
    factory-method:确定静态方法名
    -->
    <bean id="People" class = "test_b_inject_static_factory.MyBeanFactory" factory-method="createPeople"></bean>
</beans>

5.1.3、实例工厂及其测试

  1. 必须现有工厂的实例对象,然后通过实例对象去创建对象。
  2. 提供的所有方法是非静态的

配置信息

<bean id = "" factory-bean = "实例工厂" factory-method = "普通方法"></bean>

测试

 之前的学习

//People类接口
public interface People {
	public void newPeople();
}
//People类的实现类
public class PeopleImpl implements People{
	@Override
	public void newPeople() {
		// TODO 自动生成的方法存根
		System.out.println("create a people");
	}
}
//实例工厂
public class MyBeanFactory {
	public People createPeople() {
		return new PeopleImpl();
	}
}
//测试类
public class TestFactory {
	@Test
	public void demo01() {
		//1、创建工厂
		MyBeanFactory myBeanFactory = new MyBeanFactory();
		//2、通过工厂实例获取对象
		People people = myBeanFactory.createPeople();
		people.newPeople();
	}
}

学习spring后 

public class TestFactory {
	@Test
	public void demo02() {
		String xmlPath = "test_c_inject_factory/applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		People people = applicationContext.getBean("People",People.class);
		people.newPeople();
	}
}

spring配置信息 

<?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 definitions here-->
    <!-- 创建工厂实例 -->
    <bean id = "MyBeanFactory" class = "test_c_inject_factory.MyBeanFactory" ></bean>
    <!-- 获得People 
    factory-bean:获得工厂实例
    factory-method:确定普通方法的
    -->
    <bean id = "People" factory-bean = "MyBeanFactory" factory-method="createPeople"></bean>
</beans>

测试结果

 

5.2、Bean的种类

5.2.1、普通Bean:

之前的操作都是普通bean,<bean id="" class="A">,spring直接创建A的实例,并返回

5.2.2、FactoryBean:

是一个特殊的bean,具有工厂生成对象的能力,只能生成特定的对象。bean必须实现FactoryBean的接口,此接口提供一个方法getObject()用于获得特定的bean。-----<bean id="" class="FB">,先创建FB实例,然后调用getObject()方法,并返回方法的返回值

5.2.3、BeanFactory 和FactoryBean对比:

BeanFactory是工厂,用于生成任意Bean,FactoryBean是特殊的bean,用于生成另一个特定的bean。例如ProxyFactoryBean,此工厂bean用于生产代理,<bean id="" class="...ProxyFactoryBean">获得代理对象实例。AOP使用

5.3、作用域

5.3.1、作用域:

用于确定spring创建bean实例个数

类别 说明
singleton 在Spring IoC容器中仅存在一个Bean实例,Bean以单例方式存在
prototype 每次从容器中调用Bean时,都返回一个新的实例,即每次调用getBean()时,相当于执行new XxxBean()
request 每次HTTP请求都会创建一个新的Bean,仅适用于webApplicationContext环境
session 同一个HTTP Session共享一个Bean,不同Session使用不同Bean,仅适用于webApplicationContext环境
globalSession 一般用于Portlet应用环境,该作用域仅适用于webApplicationContext环境

5.3.2、取值:

                     singleton:单例,默认情况下是单例模式

                     prototype:多例,每执行一次getBean()获得一次实例

5.3.3、配置信息:

<bean id="" class="" scope="取值"></bean>
单例模式:
<bean id="People" class = "PeopleImpl"></bean>
多例模式:
<bean id="People" class = "PeopleImpl" scope = "prototype"></bean>

5.3.4、测试 

测试如下代码运行结果分别如下:

//People和PeopleImpl与上述相同
public class TestFactory {
	@Test
	public void demo01() {
		String xmlPath = "test_d_scope/applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		People people1 = applicationContext.getBean("People",People.class);
		People people2 = applicationContext.getBean("People",People.class);
		System.out.println(people1);
		System.out.println(people2);
	}
}

4、Bean的生命周期

5.4.1、初始化和销毁及其测试

  • 目标方法执行前会执行初始化方法
  • 执行销毁方法的两点要求:
  1. 容器必须close,才执行销毁方法
  2. 必须是单例模式(默认情况下就是单例模式)
<bean id = "" class = "" init-method = "初始化的方法名" destory-method = "销毁的方法名称">
init-method:用于配置初始化方法,准备数据
destroy-method:用于配置销毁方法,清理资源等

测试代码:在PeopleImpl类中添加初始化和销毁方法

public class PeopleImpl implements People {
	@Override
	public void newPeople() {
		// TODO 自动生成的方法存根
		System.out.println("create a people");
	}
	//初始化方法
	public void myInit() {
		System.out.println("my init method");
	}
	//销毁方法
	public void myDestroy() {
		System.out.println("my destroy method");
	}
}

配置文件

<?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 = "People" class = "test_e_lifecycle.PeopleImpl" init-method = "myInit" destroy-method = "myDestroy"></bean>
	
</beans>

 测试类

public class TestFactory {
	@Test
	public void demo01() throws Exception, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException {
		String xmlPath = "test_e_lifecycle/applicationContext.xml";
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		People people = applicationContext.getBean("People",People.class);
		people.newPeople();
		//要求1、容器必须close,销毁方法才执行 2、必须是单例模式
		//applicationContext.getClass().getMethod("close").invoke(applicationContext);
		//此ApplicationContext接口中没有定义close()方法,但其实现类提供
		applicationContext.close();
	}
}

测试结果:

5.4.2、BeanPOSTProcessor后处理Bean

  • spring提供的一种机制,只要去实现此接口BeanPostProcessor,并将实现类提供给spring容器,spring容器将自动的执行,在初始化方法前执行before(),在初始化方法后执行after()
  • Factory hook(钩子)that allows for custom modification of new instances,e.g.checking for marker interfaces or wrapping them with proxies.(spring提供的工厂钩子,用于修改实例对象,可以生成代理对象,是AOP的底层 )
  • 模拟:
A a = new A();
a = B.before(a);//将a的实例对象传递给后处理bean,可以生成代理对象并返回
a.init();//此时a已经是代理对象
a = B.after(a);
----开启事务----
a.method();//生成代理对象,目的是:在目标方法执行前后执行(例如开启事务、提交事务)
----提交事务----
a.destory();

 

  • 配置信息 
<bean class=""></bean>

 

  • 测试 
  • BeanPostProcessor实现类:此时返回值为null,则会出现空指针异常
public class MyBeanPostProcessor implements BeanPostProcessor{
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		// TODO 自动生成的方法存根
		System.out.println("before method");
		return bean;
	}
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		// TODO 自动生成的方法存根
		System.out.println("after method");
		return bean;
	}	
}
  • 配置文件:(5.4.1配置文件的基础上,将后处理的实现类注册给spring)
<?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 definitions here 
    init-method:用于配置初始化方法:准备数据
    destroy-method:用于配置销毁方法:清理资源等
    -->
	<bean id = "People" class = "test_e_lifecycle.PeopleImpl" init-method = "myInit" destroy-method = "myDestroy"></bean>
	<!-- 将后处理的实现类注册给spring-->
	<bean class = "test_e_lifecycle.MyBeanPostProcessor"></bean>
</beans>
  •  测试结果:在执行before()方法后,实例对象变为空,出现java.lang.NullPointerException

BeanPostProcessor的实现类中的方法添加返回值:

public class MyBeanPostProcessor implements BeanPostProcessor{
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		// TODO 自动生成的方法存根
		System.out.println("before method" + " , " + beanName);
		return bean;
	}
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		// TODO 自动生成的方法存根
		System.out.println("after method" + " , " + beanName);
		return bean;
	}	
}
  • 结果如下:此时就会按照:before()、init()、after()、实现类的方法、destroy()的顺序进行执行

  • 继续实现在执行目标方法前后进行开启事务和提交事务,修改BeanPostProcessor的实现类
public class MyBeanPostProcessor implements BeanPostProcessor{
	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		// TODO 自动生成的方法存根
		System.out.println("before method" + " , " + beanName);
		return bean;
	}
	@Override
	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		// TODO 自动生成的方法存根
		System.out.println("after method" + " , " + beanName);
		//bean是目标对象
		//生成jdk代理
		return Proxy.newProxyInstance(
				MyBeanPostProcessor.class.getClassLoader(), 
				bean.getClass().getInterfaces(), 
				new InvocationHandler() {
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						// TODO 自动生成的方法存根
						System.out.println("-----开启事事务-----");
						//执行目标方法
						Object obj = method.invoke(bean, args);
						System.out.println("-----提交事务-----");
						return obj;
					}});
	}	 
}
  • 结果:

  •  总结:两个步骤
  1. BeanPostProcessor的实现类 (涉及到动态代理)
  2. 配置  <bean class=“BeanPostProcessor的实现类”></bean>

5、属性依赖注入

5.5.1、构造方法(之后再补充)

5.5.2、setter方法

  • 普通类型属性的配置文件
<bean id = "" class = "实现类的权限定名">
    <!-- 第一种方式 (推荐)-->
    <property name = "属性名" value = "值"></property>
    <!-- 第二种方式 (不推荐)-->
    <property name = "属性名">
        <value>"值"</value>
    </property>
</bean>

 

  • 引用类型属性的配置文件
<bean id = "" class = "实现类权限定名">
    <!-- 第一种方法 (推荐)-->
    <property name = "属性名" ref = "另一个bean的id"></property>
    <!-- 第二种方法 (不推荐)-->
    <property name = "属性名">
        <ref bean = "另一个bean的id"/>
    </property>
</bean>

 

  • 测试

 准备的两个类:

public class People {
	private String pName;
	private Integer age;
	private Address homeAddr;//家庭地址
	private Address companyAddr;//公司地址
	public String getpName() {
		return pName;
	}
	public void setpName(String pName) {
		this.pName = pName;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public Address getHomeAddr() {
		return homeAddr;
	}
	public void setHomeAddr(Address homeAddr) {
		this.homeAddr = homeAddr;
	}
	public Address getCompanyAddr() {
		return companyAddr;
	}
	public void setCompanyAddr(Address companyAddr) {
		this.companyAddr = companyAddr;
	}
	@Override
	public String toString() {
		return "People [pName=" + pName + ", age=" + age + ", homeAddr=" + homeAddr + ", companyAddr=" + companyAddr+ "]";
	}
}

/********************************************************************************/
public class Address {
	private String addr;//地址信息
	private String tel;//地址的详细电话
	//添加setter方法
	public void setAddr(String addr) {
		this.addr = addr;
	}
	public void setTel(String tel) {
		this.tel = tel;
	}
	public String getAddr() {
		return addr;
	}
	public String getTel() {
		return tel;
	}
	@Override
	public String toString() {
		return "Address [addr=" + addr + ", tel=" + tel + "]";
	}	
}

编写配置文件

<?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 = "People" class = "test_f_xml_b_setter.People">
		<property name="pName" value = "jack"></property>
		<property name="age">
			<value>20</value>
		</property>
		<property name="homeAddr" ref = "homeAddr"></property>
		<property name = "companyAddr">
			<ref bean = "companyAddr"/>
		</property>
	</bean> 
	<!-- Address -->
	<bean id="homeAddr" class = "test_f_xml_b_setter.Address">
		<property name = "addr" value = "东风大道"></property>
		<property name = "tel" value = "88888888"></property>
	</bean>
	
	<bean id="companyAddr" class = "test_f_xml_b_setter.Address">
		<property name ="addr" value = "发展大道"></property>
		<property name ="tel" value = "66666666"></property>
	</bean>
</beans>

测试类

public class TestSetter {
	@Test
	public void demo01() {
		String xmlPath = "test_f_xml_b_setter/applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		People people = (People) applicationContext.getBean("People");
		String str = people.toString();
		System.out.println(str);
	}
}

测试结果:

5.5.3、P命令空间[了解]

  • 作用:对“setter方法”注入进行简化,替换<property>,替换如下
<bean id = "" class = "实现类的权限定名" p:属性名 = "普通值" p:属性名-ref = "引用值">

 

  •  p命名空间使用的前提,必须添加命名空间

  • 测试

修改配置文件如下:

<?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"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	<bean id = "homeAddr" class = "test_f_xml_c_p.Address" 
	p:addr="东风大道" 
	p:tel="88888888">
	</bean>
	<bean id = "companyAddr" class = "test_f_xml_c_p.Address" 
	p:addr="发展大道" 
	p:tel="66666666">
	</bean>
	
	<bean id = "People" class = "test_f_xml_c_p.People" 
	p:pName = "jack" 
	p:age = "20" 
	p:homeAddr-ref="homeAddr" 
	p:companyAddr-ref = "companyAddr">
	</bean>
	
</beans>

测试结果与5.5.3相同

5.5.4、SpEL(了解)

  • 对<property>进行统一编程,所有的内容都使用value
<property name="" value="#(表达式)"></property>
数字:#{123}
字符串:#{'jack'}
另外一个bean的引用:#{beanId}
操作数据:#{beanId.propName}
执行方法:#{beadId.toString()}
静态方法或字段:#{T(类的权限定名).字段|方法}

 

  • 测试
public class Customer {
    private String cname;
    private Integer age;
    private Double pi;//Math.pi
    public String getCname() {
        return cname;
    }
    public void setCname(String cname) {
        this.cname = cname;
    }
    public Double getPi() {
        return pi;
    }
    public void setPi(Double pi) {
        this.pi = pi;
    }
    @Override
    public String toString() {
        return "Customer [cname=" + cname + ", age=" + age + ", pi=" + pi + "]";
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }
}

配置文件

<?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 = "customer" class = "test_f_xml_d_spel.Customer">
    	<property name = "cname" value = "#{'jack'}"></property>
    	<property name = "age" value = "#{24}"></property>
    	<property name ="pi" value = "#{T(java.lang.Math).PI}"></property>
    </bean>
</beans>

测试类:

public class TestSpel {
	@Test
	public void demo01() {
		String xmlPath = "test_f_xml_d_spel/applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		Customer customer = applicationContext.getBean("customer",Customer.class);
		System.out.println(customer.toString());
	}

}

测试结果

6、集合注入(Array、List、Set、Map、Properties)

  • 集合的注入都是给<property>添加子标签
  • 一般情况下普通数据是<value>,引用数据是<ref>
  • 数组:<array>
  • List:<list>
  • Set:<set>
  • Map:<map>
  • Properties:<props>

测试

public class CollectionData {
	private String[] arrayData;
	private List<String> listData;
	private Set<String> setData;
	private Map<String,String> mapData;
	private Properties propsData;
	public String[] getArrayData() {
		return arrayData;
	}
	public void setArrayData(String[] arrayData) {
		this.arrayData = arrayData;
	}
	public List<String> getListData() {
		return listData;
	}
	public void setListData(List<String> listData) {
		this.listData = listData;
	}
	public Set<String> getSetData() {
		return setData;
	}
	public void setSetData(Set<String> setData) {
		this.setData = setData;
	}
	public Map<String, String> getMapData() {
		return mapData;
	}
	public void setMapData(Map<String, String> mapData) {
		this.mapData = mapData;
	}
	public Properties getPropsData() {
		return propsData;
	}
	public void setPropsData(Properties propsData) {
		this.propsData = propsData;
	}
	@Override
	public String toString() {
		return "CollectionData [\narrayData=" + Arrays.toString(arrayData) + ", \nlistData=" + listData + ", \nsetData="
				+ setData + ", \nmapData=" + mapData + ", \npropsData=" + propsData + "\n]";
	}
}

配置文件:

<?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 = "collectionData" class = "test_f_xml_e_collection.CollectionData">
   		<property name = "arrayData">
   			<array>
   				<value>array-String1</value>
   				<value>array-String2</value>
   				<value>array-String3</value>
   				<value>array-String4</value>
   			</array>
   		</property>
   		<property name = "listData">
   			<list>
   				<value>list-String1</value>
   				<value>list-String2</value>
   				<value>list-String3</value>
   				<value>list-String4</value>
   			</list> 
   		</property>
   		<property name = "SetData">
   			<set>
   				<value>set-String1</value>
   				<value>set-String2</value>
   				<value>set-String3</value>
   			</set>
   		</property>
   		<property name="mapData">
   			<map>
   				<entry key="key1" value="map-String1"></entry>
   				<entry key="key2" value="map-String2"></entry>
   				<entry key="key3" value="map-String3"></entry>
   				<entry>
   					<key><value>key4</value></key>
   					<value>map-String4</value>
   				</entry>
   			</map>
   		</property>
   		<property name="propsData">
   			<props>
   				<prop key="key1">props-String1</prop>
   				<prop key="key2">props-String2</prop>
   				<prop key="key3">props-String3</prop>
   			</props>
   		</property>
   	</bean>
</beans>

测试类:

public class TestCollection {
	@Test
	public void demo() {
		String xmlPath = "test_f_xml_e_collection/applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		CollectionData collectionData = applicationContext.getBean("collectionData",CollectionData.class);
		System.out.println(collectionData.toString());
	}

}

测试结果:

6、装配Bean基于注解

6.1、什么是注解

  • 注解:就是一个类,使用@注解名称
  • 开发中:使用注解取代xml文件
  • 使用的前提:添加命名空间,让spring扫描含有注解的类
  • 在参考文件中找到:the context schema

  •  schema的命名空间

1、命名空间声明:

          默认:xmlns=”“   <标签名>-->  <bean>

          显示:xmlns别名=”“    <别名标签名>--><context:...>

2、确定schema xsd文件位置

          xsl:schemaLocation=”名称1   位置1   名称2   位置2....“(内容都是成对的,【名称 位置】)

6.2、注解分类

1、@Component 取代 <bean class = “”>

      @Component("id) 取代 <bean id = "" class = "">

测试:

//定义一个接口
public interface People {
	public void newPeople();
}
//接口的实现类
@Component("people")
public class PeopleImpl implements People {
	@Override
	public void newPeople() {
		// TODO 自动生成的方法存根
		System.out.println("create a people");
	}
}
//测试类
public class TestDemo {
	@Test
	public void demo() {
		String xmlPath = "test_g_annotation_a_ioc/applicationContext.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		People people = applicationContext.getBean("people",People.class);
		people.newPeople();
	}
}

配置文件:

<?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="test_g_annotation_a_ioc"></context:component-scan>   
</beans>

2、web开发,提供3个@Component注解衍生注解(功能一样),取代<bean class="">

      @Repository:dao层

      @Service:service层

      @Controller:web层

3、依赖注入    给私有字段设置,也可以给setter方法设置

      普通值:@value("")

      引用值:

               方式一:按照【类型】注入    

                     @Autowired

               方式二:按照【名称】注入1

                     @Autowired

                     @Qualifier("名称")

               方式三:按照【名称】注入2

                     @Resource("名称")

测试:

@Controller("studentActionId")
public class StudentAction {
	@Autowired//默认  按照类型注入
	private StudentService studentService;
	public void execute() {
		studentService.addStudent();
	}
}
//service
public interface StudentService {
	public void addStudent();
}
//StudentService的实现类
@Service
public class StudentServiceImpl implements StudentService {
	private StudentDao studentDao;
	@Autowired//默认  按照类型注入
	@Qualifier("studentDaoId")
	public void setStudentDao(StudentDao studentDao) {
		this.studentDao = studentDao;
	}
	@Override
	public void addStudent() {
		// TODO 自动生成的方法存根
		//System.out.println("service");
		studentDao.addStudent();
	}
}
//dao
public interface StudentDao {
	public void addStudent();
}
//StudentDao的实现类
@Repository("studentDaoId")
public class StudentDaoImpl implements StudentDao {
	@Override
	public void addStudent() {
		// TODO 自动生成的方法存根
		System.out.println("create a student");
	}
}

测试类:

public class TestDemo {
	@Test
	public void demo() {
		ApplicationContext applicationContext = new 
				ClassPathXmlApplicationContext("test_g_annotation_b_web/applicationContext.xml");
		StudentAction studentAction = (StudentAction) applicationContext.getBean("studentActionId");
		studentAction.execute();
	}
}

配置文件

<?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="test_g_annotation_b_web"></context:component-scan>
</beans>

 

6.3、生命周期

     初始化:@PostConstruct

     销毁:@PreDestory

6.4、作用域

     @Scope("prototype") 多例

7、注解和xml混合使用

1、将所有的bean都配置在xml中 <bean id = “” class = “”>

2、将所有的依赖都使用注解  @Autowired

      默认不生效,为了生效,需要在xml文件中配置:<context annotation-config></context annotation-config>

总结:注解1 :<context-component-scan base-package ="">

           注解2 :<context annotation-config>

1、一般两个注解不一起使用

1、"注解1"扫描含有注解(@Component等)类的,注入的注解自动的生效,"注解2"只在xml和注解(注入)混合使用时,使注入注解生效

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章