Spring学习笔记(一)Spring入门

1.引入

 之前一直在用Spring、SpringMVC、MyBatis开发,但是却没有系统学习、整理这三大框架的知识点。从以前的SSH到现在的SSM,SpringMVC取代了Struts2,Mybatis取代了Hibernate,唯一不变的是Spring,正如它的中午含义 — —“春天”一般,它是JAVA程序员的春天,没有它兴许就不会有当下如此兴盛的JAVA时代。而Spring的博大精深,其原理更是非常值得我们去探究的。于是打算写下一系列的Spring博客,梳理一下其中的知识点。 

 Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EEDevelopment and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 J2EE 应用程序开发提供集成的框架。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。简单来说,Spring是一个分层的JavaSE/EE full-stack(一站式) 轻量级开源框架。

 Spring的核心是控制反转(IoC)面向切面(AOP)。


2.Spring的优点

  Spring有很多优点,主要有一下几点:

  •   方便解耦,简化开发  (高内聚低耦合)

     Spring就是一个大工厂(容器),可以将所有对象创建和依赖关系维护,交给Spring管理

     spring工厂是用于生成bean

  •   AOP编程的支持

     Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能

  •   声明式事务的支持

     只需要通过配置就可以完成对事务的管理,而无需手动编程

  •   方便程序的测试

    Spring对Junit4支持,可以通过注解方便的测试Spring程序

  •   方便集成各种优秀框架

    Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持

  •   降低JavaEE API的使用难度

    Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低


 看完以上,你肯定会有不少的困惑,不要着急,不用担心,接着往下学习,所有的问题都会逐步化解。


3.Spring的体系结构

  Spring 框架是一个分层架构,,它包含一系列的功能要素并被分为大约20个模块。这些模块分为Core Container、Data Access/Integration、Web、AOP(Aspect Oriented Programming)、Instrumentation和测试部分,如下图所示:

1.Core Container : 核心容器

  Beans : 管理Bean

  Core : 核心

  Context :上下文(最终都会体现在配置文件)

  Expression Language :SpEL表达式

2.AOP : 切面编程

  Aspects : AOP框架

3.JDBC : JDBC Template开发

  ORM : 整合hibernate

  Transactions :事物管理Tx


4.Web : web开发

  Struts:整合Struts

5.Test : 整合Junit


  核心容器则为:beanscorecontextexpression 。

4.Spring环境搭建

   搭建Spring环境的第一步,就是导入JAR包。Spring的JAR包永远记住一个原则:

  4 + 1  : 4个核心(beans、core、context、expression上文所述的核心容器) + 1个依赖(commons-loggins...jar)

 

配置文件:

  • 位置:任意,开发中一般在classpath下(src)
  • 名称:任意,开发中常用applicationContext.xml
  • 内容:添加schema约束
  • 约束文件位置:spring-framework-3.2.0.RELEASE\docs\spring-framework-reference\html\xsd-config.html


5.IOC控制反转

  • 提供UserService接口及其实现类
  • 获得UserService实现类实例 

  如果没有学习过Spring,获取实例直接new一个对象即可,但是现在,我们正在学习Spring,它的神奇之一在于,Spring可以为我们创建对象实例 — —即IoC 控制反转(Inverse of Control)。之后需要实例对象时,从Spring工厂(容器)中获得,需要将实现类的全限定名称配置到xml文件中。

   根据一个简单的例子,我们可以入门IOC。

public interface UserService {

	public void addUser();
}

public class UserServiceImp implements UserService {

	@Override
	public void addUser() {
		System.out.println("hello Ioc ");
	}

}

配置文件
<?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">
	<!-- 配置service 
		<bean> 配置需要创建的对象
			id :用于之后从spring容器获得实例时使用的
			class :需要创建实例的全限定类名
	-->
	<bean id="userServiceId" class="com.spring.ioc.UserServiceImp"></bean>
</beans>

测试类:

public class TestIoc {

	@Test
	public void testBefore() throws Exception {
		//学习Spring之前
		UserService  userService = new UserServiceImp(); 
		userService.addUser();
	}
	
	@Test
	public void testIoc() throws Exception {
		//学习Spring之后
		//从Spring容器中获得
		//1.获得容器
		String xmlPath = "com/spring/ioc/beans.xml";
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); 
		//2.获得内容--不再需要自己去new  都是从spring容器中获得
		UserService userService = (UserService) applicationContext.getBean("userServiceId");
		userService.addUser();
	}
}

6.核心API

 

  • BeanFactory :这是一个工厂,用于生成任意bean。采取延迟加载,第一次getBean时才会初始化Bean

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

       - ClassPathXmlApplicationContext 用于加载classpath(类路径、src)下的xml

              加载xml运行时位置 --> /WEB-INF/classes/...xml

        - FileSystemXmlApplicationContext 用于加载指定盘符下的xml

              加载xml运行时位置 --> /WEB-INF/...xml

                     通过java webServletContext.getRealPath() 获得具体盘符

        @Test
	public void demo02(){
		//使用BeanFactory  --第一次条用getBean实例化
		String xmlPath = "com/<span style="font-family:SimSun;">spring</span>/<span style="font-family:SimSun;">di</span>/beans.xml";
		
		BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource(xmlPath));
		
		BookService bookService = (BookService) beanFactory.getBean("bookServiceId");
		
		bookService.addBook();
		
	}

7.装配Bean

7.1基于XML

7.1.1实例化方式

  3种bean实例化方式:默认构造、静态工厂、实例工厂

  • 默认构造:
    <bean id="" class="">  必须提供默认构造

  • 静态工厂:

       常用与spring整合其他框架(工具)

       静态工厂:用于生成实例对象,所有的方法必须是static

<bean id=""  class="工厂全限定类名(<span style="font-family:SimSun;">包名+类名</span>)"  factory-method="静态方法">

eg:

工厂类

public class MyBeanFactory {

	/**
	 * 创建实例 
	 * @return
	 */
	public static UserService createUserService(){
		return new UserServiceImp();
	}
}
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">
	<!-- 配置service 
		<bean> 配置需要创建的对象
			id :用于之后从spring容器获得实例时使用的
			class :需要创建实例的全限定类名
			factory-method:调用的静态工厂方法
	-->
	<bean id="userServiceId" class="com.spring.di.MyBeanFactory" factory-method="createUserService"></bean>
</beans>


测试类:
public class TestStaticFactory {

	//学习spring之前
	@Test
	public void demo01() throws Exception {
		UserService userService = MyBeanFactory.createUserService();
		userService.addUser();
	}
	//学习spring之后
	@Test
	public void demo02() throws Exception {
		//spring工厂
		String mPath = "com/spring/di/beans.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(mPath);
		UserService userService = applicationContext.getBean("userServiceId", UserService.class);
		userService.addUser();
	}
}

  • 实例工厂

        必须先有工厂实例对象,通过实例对象创建对象。提供所有的方法都是“非静态”的。

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 id="myBeanFactoryId" class="com.spring.myFactory.MyBeanFactory" ></bean>
	<!-- 获得userService 
	factory-bean 确定工厂实例
	factory-method 确定普通方法
	-->
	<bean id="userServiceId" factory-bean="myBeanFactoryId" factory-method="createUserService"></bean>
</beans>

测试类
        //学习spring之前
	@Test
	public void demo01() throws Exception {
		MyBeanFactory myBeanFactory = new MyBeanFactory();
		UserService userService = myBeanFactory.createUserService();
		userService.addUser();
	}
	//学习spring之后
	@Test
	public void demo02() throws Exception {
		//springg工厂
		String mPath = "com/spring/myFactory/beans.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(mPath);
		UserService userService = applicationContext.getBean("userServiceId", UserService.class);
		userService.addUser();
	}
	

7.1.2 Bean的种类
  •  普通bean:之前操作的都是普通bean。<beanid="" class="A"> ,spring直接创建A实例,并返回

  •   FactoryBean:是一个特殊的bean,具有工厂生成对象能力,只能生成特定的对象。

       bean必须使用 FactoryBean接口,此接口提供方法 getObject() 用于获得特定bean。

       <beanid="" class="FB"> 先创建FB实例,使用调用getObject()方法,并返回方法的返回值

              FB fb = new FB();

              returnfb.getObject();

官方文档中的描述:    

Interface to be implemented by objects used within a BeanFactory which are themselves factories. 
If a bean implements this interface, it is used as a factory for an object to expose,
not directly as a bean instance that will be exposed itself.

NB: A bean that implements this interface cannot be used as a normal bean. 
A FactoryBean is defined in a bean style, 
but the object exposed for bean references (getObject() is always the object that it creates. 


  •  BeanFactory 和 FactoryBean 对比?

       BeanFactory:工厂,用于生成任意bean。

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


7.1.3作用域
  • 作用域:用于确定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 环境

       singleton 单例,默认值。

       prototype 多例,每执行一次getBean将获得一个实例。例如:struts整合spring,配置action多例。

  • 配置信息
<bean id="" class=""  scope="">

<bean id="userServiceId" class="com.<span style="font-family:SimSun;">spring</span>.scope.UserServiceImpl" scope="prototype" ></bean>


7.1.4生命周期
  1. 初始化和销毁

     -目标方法执行前后执行后,将进行初始化或销毁。

<bean id="" class="" init-method="初始化方法名称"  destroy-method="销毁的方法名称">

示例代码:
public class UserServiceImp implements UserService {

	@Override
	public void addUser() {
		System.out.println("My Lisfe Cycle");
	}

	public void myInit(){
		System.out.println("myInit");
	}
	
	public void myDestory(){
		System.out.println("myDestory");
	}
	
}

配置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">
	<!--  
		init-method 用于配置初始化方法,准备数据等
		destroy-method 用于配置销毁方法,清理资源等
	-->

	<bean id="userServiceId" class="com.spring.lifeCycle.UserServiceImp"
		init-method="myInit" destroy-method="myDestory"></bean>
</beans>


测试类:
@Test
	public void testLife() throws Exception {
		//学习Spring之后
		//从Spring容器中获得
		//1.获得容器
		String xmlPath = "com/spring/lifeCycle/beans.xml";
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); 
		//2.获得内容--不再需要自己去new  都是从spring容器中获得
		UserService userService = (UserService) applicationContext.getBean("userServiceId");
		userService.addUser();
		//要求:1.容器必须close,销毁方法执行; 2.必须是单例的
//		applicationContext.getClass().getMethod("close").invoke(applicationContext);
		// * 此方法接口中没有定义,实现类提供
		applicationContext.close();

	}

执行结果:



  2.BeanPostProcessor 后处理Bean

  • spring 提供一种机制,只要实现此接口BeanPostProcessor,并将实现类提供给spring容器,spring容器将自动执行,在初始化方法前执行before(),在初始化方法后执行after() 。 配置<bean class="">

    参见Spring官方文档:

  • Factory hook that allows for custom modification of new bean instances, e.g. checking for marker interfaces or wrapping them with proxies.(来源Spring官方文档)

   spring提供工厂钩子,用于修改实例对象,可以生成代理对象,是AOP底层。

   这并不好理解,我们可以用伪代码模拟一下过程。
A a =new A();
a = B.before(a)			<span style="font-family:SimSun;">//</span> 将a的实例对象传递给后处理bean,可以生成代理对象并返回。
a.init();
a = B.after(a);

a.addUser();		//生成代理对象,目的在目标方法前后执行(例如:开启事务、提交事务)

a.destroy()


示例代码:

编写实现类

public class MyBeanPostProcessor implements BeanPostProcessor{

	@Override
	public Object postProcessBeforeInitialization(Object bean, String beanName)
			throws BeansException {
		System.out.println("Before" + beanName);
		return bean;
	}

	@Override
	public Object postProcessAfterInitialization(final Object bean, String beanName)
			throws BeansException {
		System.out.println("After" + 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 {
												System.out
														.println("开启事物");
												//执行目标方法
												method.invoke(bean, args);
												System.out
														.println("提交事物");
												//执行目标方法
												return null;
											}
										});
	}

	

}

配置
<bean class="com.spring.lifeCycle.MyBeanPostProcessor"></bean>

结果:



学习完生命周期后,我们必须思考两个问题:


Q1:后处理bean作用某一个目标类,还是所有目标类?

A:所有


Q2:如何只作用一个?

A:通过“参数2”beanName进行控制

7.1.4属性依赖注入
  1.依赖注入方式:手动装配 和 自动装配
  2.手动装配:一般进行配置信息都采用手动
  •  基于xml装配:构造方法、setter方法
  •  基于注解装配:(详见7.2)

  3.自动装配:struts和spring 整合可以自动装配
  •  byType:按类型装配
  •  byName:按名称装配
  •  constructor构造装配,
  •  auto: 不确定装配

7.1.4.1构造方法

   <constructor-arg>:用于配置构造方法一个参数argument
             name :参数的名称
             value:设置普通数据
             ref:引用数据,一般是另一个bean id值
             index :参数的索引号,从0开始 。如果只有索引,匹配到了多个构造方法时,默认使用第一个。
             type :确定参数类型

示例代码:

package com.spring.xml.constructor;

public class User {

	private Integer uid;
	private String username;
	private Integer age;
	
	public User(String username, Integer age) {
		super();
		this.username = username;
		this.age = age;
	}
	public Integer getUid() {
		return uid;
	}
	public void setUid(Integer uid) {
		this.uid = uid;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "User [uid=" + uid + ", username=" + username + ", 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">
	
	<!-- 构造方法注入 
		* <constructor-arg> 用于配置构造方法一个参数argument
			name :参数的名称
			value:设置普通数据
			ref:引用数据,一般是另一个bean id值
			
			index :参数的索引号,从0开始 。如果只有索引,匹配到了多个构造方法时,默认使用第一个。
			type :确定参数类型
		例如:使用名称name
			<constructor-arg name="username" value="jack"></constructor-arg>
			<constructor-arg name="age" value="18"></constructor-arg>
		例如2:【类型type 和  索引 index】
			<constructor-arg index="0" type="java.lang.String" value="1"></constructor-arg>
			<constructor-arg index="1" type="java.lang.Integer" value="2"></constructor-arg>
	-->
 
	<bean class="com.spring.xml.constructor.User" id="userId">
	<constructor-arg name="username"></constructor-arg>
	<constructor-arg name="age"></constructor-arg>
	</bean>
</beans>


测试类:

public class TestUser {

	@Test
	public void demo01() throws Exception {
		String xmlPath = "com/spring/xml/constructor/beans.xml";
		ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext(xmlPath);
		User bean = classPathXmlApplicationContext.getBean("userId", User.class);
		System.out.println(bean);
	}

7.1.4.2setter方法

setter方法,本质上就是去寻找该对象的setter方法,把值设置进去,毕竟简单,直接看示例代码就好。

<?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">
	

	<!-- setter方法注入 
		* 普通数据 
			<property name="" value="值">
			等效
			<property name="">
				<value>值
		* 引用数据
			<property name="" ref="另一个bean">
			等效
			<property name="">
				<ref bean="另一个bean"/>
	
	-->

	<bean id="personId" class="com.spring.xml.setter.Person">
		<property name="pname" value="keo"></property>
		<property name="age">
			<value>21</value>
		</property>
		
		<property name="homeAddr" ref="homeAddrId"></property>
		<property name="companyAddr">
			<ref bean="companyAddrId"/>
		</property>
	</bean>
	
	<bean id="homeAddrId" class="com.spring.xml.setter.Address">
		<property name="addr" value="beijing"></property>
		<property name="tel" value="911"></property>
	</bean>
	<bean id="companyAddrId" class="com.spring.xml.setter.Address">
		<property name="addr" value="北京海淀"></property>
		<property name="tel" value="120"></property>
	</bean>

</beans>


7.1.4.3.P命令空间

  • 对“setter方法注入”进行简化,替换<property name="属性名">,而是在

              <beanp:属性名="普通值"  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 
       		<span style="font-family:SimSun;">            </span>http://www.springframework.org/schema/beans/spring-beans.xsd"
       					   >
	

示例配置:

<?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 
       		<span style="font-family:SimSun;">            </span>http://www.springframework.org/schema/beans/spring-beans.xsd"
       					   >
	

	<bean id="personId" class="com.spring.xml.p.Person" 
		p:pname="keo" p:age="22" 
		p:homeAddr-ref="homeAddrId" p:companyAddr-ref="companyAddrId">
	</bean>
	
	<bean id="homeAddrId" class="com.spring.xml.p.Address"
		p:addr="DG" p:tel="beijing">
	</bean>
	<bean id="companyAddrId" class="com.spring.xml.p.Address"
		p:addr="DG" p:tel="shanghai">
	</bean>


</beans>


在真正的开发中,这种方式用的还是比较少的,相对而言,property配置会更多一些。


7.1.4.4SpEL表达式

 

  • 对<property>进行统一编程,所有的内容都使用value

   <propertyname="" value="#{表达式}">

   #{123}、#{'jack'} : 数字、字符串

   #{beanId} :另一个bean引用

   #{beanId.propName} :操作数据

   #{beanId.toString()} :执行方法

   #{T(类).字段|方法}:静态方法或字段

   ...

这种方法,用的比较少,所以了解一下即可。有兴趣的朋友可以再去深入了解。

示例代码

<span style="font-family:SimSun;font-size:14px;"><!-- 
		<property name="cname" value="#{'jack'}"></property>
		<property name="cname" value="#{customerId.cname.toUpperCase()}"></property>
			通过另一个bean,获得属性,调用的方法
		<property name="cname" value="#{customerId.cname?.toUpperCase()}"></property>
			?.  如果对象不为null,将调用方法
	-->
	<bean id="customerId" class="com.spring.xml.spel.Customer" >
		<property name="cname" value="#{customerId.cname?.toUpperCase()}"></property>
		<property name="pi" value="#{T(java.lang.Math).PI}"></property>
	</bean></span>


7.1.4.5集合注入

  •     集合的注入都是给<property>添加子标签

         数组:<array>

         List:<list>

         Set:<set>

         Map:<map> ,map存放k/v 键值对,使用<entry>描述

         Properties:<props>  <propkey=""></prop>   

         普通数据:<value>

         引用数据:<ref>

示例代码

public class CollData {

	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 "CollData [\narrayData=" + Arrays.toString(arrayData)
				+ ", \nlistData=" + listData + ",\n setData=" + setData
				+ ", \nmapData=" + mapData + ", \npropsData=" + propsData + "]";
	}
	
}

配置文件

<bean id="collDataId" class="com.<span style="font-family:SimSun;">spring.</span>xml<span style="font-family:SimSun;">.</span>CollData" >
		<property name="arrayData">
			<array>
				<value><span style="font-family:SimSun;">DD</span></value>
				<value>D<span style="font-family:SimSun;">DD</span></value>
				<value><span style="font-family:SimSun;">神</span></value>
				<value><span style="font-family:SimSun;">keo</span></value>
			</array>
		</property>
		
		<property name="listData">
			<list>
				<value><span style="font-family:SimSun;">张伟</span></value>
				<value><span style="font-family:SimSun;">吕子乔</span></value>
				<value><span style="font-family:SimSun;">展博</span></value>
				<value>曾小贤</value>
			</list>
		</property>
		
		<property name="setData">
			<set>
				<value><span style="font-family:SimSun;">你好</span></value>
				<value><span style="font-family:SimSun;">哈哈</span></value>
				<value><span style="font-family:SimSun;">嘻嘻</span></value>
			</set>
		</property>
		
		<property name="mapData">
			<map>
				<entry key="jack" value="杰克"></entry>
				<entry>
					<key><value>rose</value></key>
					<value>肉丝</value>
				</entry>
			</map>
		</property>
		
		<property name="propsData">
			<props>
				<prop key="高富帅">嫐</prop>
				<prop key="白富美">嬲</prop>
				<prop key="男屌丝">挊</prop>
			</props>
		</property>
	</bean>

测试类

public class TestCllection {

	@Test
	public void demo01() throws Exception {
		String xmlPath = "com/spring/xml/collection/beans.xml";
		ApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext(xmlPath);
		CollData c = classPathXmlApplicationContext.getBean("collDataId",CollData.class);
		System.out.println(c);
	}

7.2基于注解

  •   注解:就是一个类,使用@注解名称
  •   开发中:使用注解 取代 xml配置文件。


1. @Component取代<bean class="">

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

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

       @Repository:dao层

       @Service:service层

       @Controller:web层

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

       普通值:@Value("")

       引用值:

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

                     @Autowired

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

                     @Autowired

                     @Qualifier("名称")

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

                     @Resource("名称")

4.生命周期

       初始化:@PostConstruct

       销毁:@PreDestroy

5.作用域

       @Scope("prototype") 多例



注意:

   注解使用前提,添加命名空间,让spring扫描含有注解类

<pre class="programlisting"><span class="hl-directive" style="color:maroon;"><?xml version="1.0" encoding="UTF-8"?></span>
<span class="hl-tag"><beans</span> <span class="hl-attribute">xmlns</span>=<span class="hl-value">"http://www.springframework.org/schema/beans"</span>
       <span class="hl-attribute">xmlns:xsi</span>=<span class="hl-value">"http://www.w3.org/2001/XMLSchema-instance"</span>
       <span class="bold"><strong>xmlns:aop="http://www.springframework.org/schema/aop"</strong></span>
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
<span class="bold"><strong>http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"</strong></span>>

<em class="lineannotation"><span class="lineannotation"><!-- bean definitions here --></span></em>

<span class="hl-tag"></beans></span>

 

D.2.8 The context schema

The context tags deal with ApplicationContext configuration that relates to plumbing - that is, not usually beans that are important to an end-user but rather beans that do a lot of grunt work in Spring, such asBeanfactoryPostProcessors. The following snippet references the correct schema so that the tags in thecontext namespace are available to you.

(spring官方文档对这段命名空间的描述)

示例代码:

<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.spring.annotation"></context:component-scan>
</beans>
@Component("userServiceId")
public class UserServiceImp implements UserService {

	@Override
	public void addUser() {
		System.out.println("annotation");
	}

}


测试类

public class TestAnnoIoc {

	@Test
	public void demo01() throws Exception {
		String xmlPath = "com/spring/annotation/beans.xml";
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
		UserService userService = (UserService) applicationContext.getBean("userServiceId", UserServiceImp.class);
		userService.addUser();
	
	}
}


分层代码示例:

Dao层:

public interface StudentDao {

	void save();

}

@Repository("studentDaoId")
public class StudentDaoImpl implements StudentDao {

	@Override
	public void save() {
		System.out.println("dao");
	}

}

Service层

public interface StudentService {

	void addStudent();

}

@Service
public class StudentServiceImpl implements StudentService {
	
	private StudentDao studentDao;
	
	@Autowired
	@Qualifier("studentDaoId")
	public void setStudentDao(StudentDao studentDao) {
		this.studentDao = studentDao;
	}

	@Override
	public void addStudent() {
		studentDao.save();
	}

}

Web(Control)层

@Controller("studentActionId")
public class StudentAction {
	
	@Autowired //默认按照类型
	private StudentService studentService;

	public void execute() {
		studentService.addStudent();
	}

}

匹配示意图:

                                                                                                                              图一



                                                                                                                    图二


                                                                                          图三


如果注解与XML配置混合使用呢??

1.将所有的bean都配置xml中

       <beanid="" class="">

2.将所有的依赖都使用注解

       @Autowired

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

 

总结:

注解1:<context:component-scanbase-package=" ">

注解2:<context:annotation-config>

1.一般情况两个注解不一起使用。

2. “注解1”扫描含有注解(@Component等)类,注入注解自动生效。

       “注解2”只在xml和注解(注入)混合使用时,使注入注解生效。

 


学习到这里,你已经对Spring有了一定的认识。下一篇博客,我将继续整理spring的知识点,介绍Spring另一个核心:AOP。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值