Spring-01 IoC

1. 安装spring插件

SPRING TOOL SUITE 是一个 Eclipse 插件,利用该插件可以更方便的在 Eclipse 平台上开发基于 Spring 的应用。

  • Install New Software…
  • Add…
  • Location
  • 选择Navigate to springsource-tool-suite-3.4.0.RELEASE-e4.3.1-updatesite.zip
  • 取消勾选 Contact all updata…
  • 点击“Acailable Software Sites” 蓝色字体 取消所有http的选项勾选
  • 一直下一步
  • 关于错误处理
    jdk版本 spring 版本 eclipse版本 引起的

2. spring概述

2.1spring是个啥?

开源的轻量级的框架,一个IOC(DI)和AOP容器框架,关于框架的特性,spring俗称开发框架的粘合剂

  • 轻量级:Spring是非侵入性的,基于Spring开发的应用中的对象可以不依赖Spring的API
  • 依赖注入:(DI—dependency Injection、IOC —Inversion of Control)
  • 面向切面编程:(AOP aspect oriented programming)
  • 容器:Spring 是个容器,因为它包含并且管理应用对象的生命周期
  • 框架:Spring实现了使用简单的组件配置组合成一个复杂的应用,在Spring中可以使用xml和java注解组合这些对象
  • 一站式:在IOC和AOP的基础上可以整合各个企业应用的开源框架和第三方类库
    spring提供了JavaEE各层的解决方案
    web表现层(页面数据显示、页面跳转调度):SpringMVC Struts2
    service业务层(业务处理和功能逻辑、事务控制):IoC、AOP、事务控制
    dao持久层(数据存取和封装):jdbcTemplate,HibernateTemplate,ORM框架
    在这里插入图片描述

2.2spring框架runtime

  • test:spring提供的测试功能
    提供对使用JUnit和TestNG来测试Spring组件的支持,它提供一致的ApplicationContexts并缓存这些上下文,它还能提供一些mock对象,使得你可以独立的测试代码
  • AOP:实现aop功能需要的依赖
    • AOP:提供了符合AOP 联盟规范的面向方面的编程实现,让你可以定义如方法拦截器和切入点,从逻辑上讲,可以减弱代码的功能耦合,清晰的被分离开。而且,利用源码级的元数据功能,还可以将各种行为信息合并到你的代码中
    • Aspect:提供了对AspectJ的集成
    • Instrumentation
  • WEB:需要spring完成web相关功能时需要
    • Web:提供了基础的web功能,例如文件上传,集成IoC容器,远程过程访问及对web Service支撑
    • Servlet:提供了Web应用的MVC实现,Spring MVC框架提供了基于注解的请求资源注入、更简单的数据绑定、数据验证等及一套非常易用的JSP标签,完全无缝与Spring其他技术协作
    • Portlet模块,提供了在Portlet环境下的MVC实现
  • Data Access/Integration(数据访问/集成部分):spring封装数据访问层相关内容
    • JDBC:Spring对JDBC封装后的代码
    • ORM:提供了常用的“对象/关系”映射APIs的集成层,封装了持久层框架的代码:如Hibernate MyBatis
    • transactions:对应spring-tx.jar,声明式事务使用,只要是Spring管理的对象都能得到spring管理事务的好处
    • OXM:提供一个支持Object和XMl进行映射的抽象层
    • JMS模块:提供一套"消息生产者、消费者"模板用于更加简单的使用JMS,JMS用于用于在两个应用程序之间,或分布式系统中发送消息,进行异步通信。
  • Core Container:核心容器,Spring启动的基本条件
    • Beans:Spring负责创建对象并管理对象
    • Core:核心类 ,和Beans模块提供了Spring最基础的功能,提供了IoC和依赖注入的特性,这里的基础概念是BeanFactory,它提供对Factory模式的经典实现来消除对程序性单例模式的需要,并真正地允许你从程序逻辑中分离出依赖关系和配置。
    • Context:上下文参数,获取外部资源或管理注解
      Context模块基于Core和Beans来构建,Context封装包继承了beans包的功能,还增加了其他的功能,核心接口是ApplicationContext
    • SqEl:expression.jar 表达式语言模块,提供了在运行期间查询和操作对象图的强大能力。 "

2.3 spring的优点

  1. 方便解耦,简化开发
    Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理
  2. AOP编程的支持
    Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能
  3. 声明式事务的支持
    只需要通过配置就可以完成对事务的管理,而无需手动编程
  4. 方便程序测试
    对Junit4支持,可以通过注解方便的测试Spring程序
  5. 方便集成各种优秀的框架
    不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:Struts、Hibernate、MyBatis、Quartz、webservice、activity等)的直接支持
  6. 降低JavaEE API的使用难度
    Spring 对JavaEE开发中非常难用的一些API(JDBC、JavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低

3. IoC&DI

IOC控制返转

IoC完成的事情   由程序员主动通过new实例化对象事情转交给Spring完成

IoC是一种思想,是控制反转的思想,解耦的思想

spring是该思想的一种实现,因此spring容器也通常称之为IoC容器

将对象创建权利交给Spring工厂进行管理

控制:控制类的对象

反转:转交给spring对象

底层实现:工厂模式+反射+配置文件

最大作用:解耦  ,解除了对象管理和程序员之间的耦合,程序员不需要管理对象

DI 依赖注入

在spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件(将另外一个Bean对象动态的注入到另外一个bean中)

IoC和DI是同一件事情,都是将对象控制权交给第三方(spring)管理,只是站在不同角度而已(IoC是目的,DI是手段)	

    简单的说,就是我们类里需要另一个类,只需要让Spring帮我们创建 ,这叫做控制反转,然后Spring帮我们将需要的对象设置到我们的类中,这叫做依赖注入。

4. 代码实现

4.1导包

四个核心包一个日志包

commous-logging-1.1.3.jar
spring-beans-4.2.4RELEASE.jar
spring-context-4.2.4RELEASE.jar
spring-core-4.2.4RELEASE.jar
spring-expression-4.2.4RELEASE.jar

4.2配置文件

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">
<!-- id 表示获取到对象标识class 创建哪个类的对象-->
<bean id="people" class="com.yn.People"/>
</beans>

4.3People类

public class Person {

	private String name;
	private int age;
	
	public Person() {
		super();
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
}

4.4测试

public static void main(String[] args) {
	
		ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
		//使用Java反射来实现  默认是单例模式来创建对象
		Person p=(Person)ac.getBean("person");
		Person p2 = ac.getBean("person",Person.class);		
		System.out.println(p);
    	System.out.println(p2);
			
}	

5. 依赖注入的三种方式

  • 属性注入

    • 通过构造方法设置值.
    • 设置注入(通过 set 方法)
    • 如果属性是基本数据类型或 String 等简单
    • <bean id="people" class="com.yn.People">
      		<property name="name" value="tom" ></property>	
      		<property name="age" value="18"></property>
      </bean>
      
    • 如果属性是 Set<?>
    • <property name="sets">
          <set>
              <value>1</value>
              <value>2</value>
              <value>3</value>
              <value>4</value>
      	</set>
      </property>
      
    • 如果属性是 List<?>
    • <property name="list">
          <list>
              <value>1</value>
              <value>2</value>
              <value>3</value>
          </list>
      </property>
      
    • 如果属性是数组
    • <property name="strs" >
          <array>
              <value>1</value>
              <value>2</value>
              <value>3</value>
          </array>
      </property>
      
    • 如果属性是 map
    • <property name="map">
          <map>
              <entry key="a" value="b" >
              </entry>
              <entry key="c" value="d" >
              </entry>
          </map>
      </property>
      
    • 如果属性 Properties 类型
    • <property name="demo">
          <props>
              <prop key="key">value</prop>
              <prop key="key1">value1</prop>
          </props>
      </property>
      
    • 配置工具类集合
    • <!-- 首先导入util命名空间 -->
      xmlns:util="http://www.springframework.org/schema/util"
      <util:list id="pets">
          <ref bean="cat"/>
          <ref bean="dog"/>
      </util:list>
      
    • 使用p命名空间
    •   <!-- 首先导入p命名空间 -->
        xmlns:p="http://www.springframework.org/schema/p"
        <bean id="pet" class="cn.yn.Pet" p:petName="鹦鹉" p:petType="鸟"></bean>
        <bean id="test1" class="cn.yn.Person" p:name="张全蛋" p:age="10" 
              p:pet-ref="pet"></bean>
        <!-- 使用p命名空间(spring 2.5版本引入的) 可以简化bean的配置 -->
      
    • null值
    • <constructor-arg name="name">
      	<null/>
      </constructor-arg>
      
    • 自动装配
    • autowire = "byName" || "byType"  不推荐使用。
      <!-- 
      		可以通过autowire属性设置bean的自动装配 。
      		byName 根据bean的名字和bean,setter风格的属性名进行自动装配,如有匹配则自动装配,没有不装配。
      		byType 根据bean的类型,和当前bean属性的类型进行自动装配。如果ioc容器有1个以上类型匹配的bean的时候,则会抛出异常。
      		constructor 当前bean中有多个构造器的时候 会很复杂不推荐使用该方式。
      		
      		自动装配的弊端。
      		1.autowire属性是配置在bean级别的,如果只希望装配个别属性,则不够灵活。
      		2.要么根据类型 要么根据名字自动装配 不能两个一起使用。
      		在使用spring整合第三方框架的时候 会使用autowire 。。。
      	 -->
      	<bean id="xm" class="cn.yn.Person" p:name="小明" autowire="byType">
      	</bean>
      	
      	<bean id="pet1" class="cn.yn.Pet" p:petName="发福蝶"></bean>
      	<bean id="pet2" class="cn.yn.Pet" p:petName="小脑斧"></bean>
      
  • 构造器注入

    • 无参构造创建:默认情况.
    • 有参构造创建:需要明确配置
      • 需要在类中提供有参构造方法
      • 在 配置文件 中设置调用哪个构造方法创建对象
    • index : 参数的索引,从 0 开始
    • name: 参数名
    • type:类型(区分开关键字和封装类 int 和 Integer)
    • ref:引用其他对象 <![CDATA[]]>
  • 工厂方法注入 很少使用,不推荐

6. Bean 的作用域

由spring创建的bean对象在什么情况下有效。

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

Porlet: 基于Java的web组件

项目开发中通常使用singleton和prototype

7.Bean的生命周期

通过spring工厂,可以控制bean的生命周期

  • 通过构造器或工厂方法创建Bean实例
  • 为Bean的属性设置值,和对其他Bean的引用
  • 调用Bean的初始化方法
  • Bean可以使用了
  • 当容器关闭,调用Bean的销毁方法

在 Bean 的声明里设置 init-method 和 destroy-method 属性, 为 Bean 指定初始化和销毁方法.

spring提供可一个Bean后置处理器,允许在调用初始化方法前后对Bean进行额外的处理

Bean后置处理器对IoC容器里所有的Bean实例逐一处理,作用:检测bean属性的正确性,或者根据特定的标准更改bean属性

8. 使用外部属性文件

在配置文件中配置bean时,有时候需要混入系统部署的数据信息。

例如:文件路径,数据源配置。

实际上需要将这些数据跟bean的配置分离。

spring提供了一个PropertyPlaceholderConfigurer的BeanFactory后置处理器。

可以使用${var}的形式,从属性配置文件中读取属性,并使用这些属性。

spring,2.5之后。可以通过<context:property-placeholder location=“classpath:db.properties”

<context:property-placeholder location="classpath:db.properties"></context:property-placeholder>
	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
		<property name="user" value="root"></property>
		<property name="password" value="root123"></property>
		<property name="driverClass" value="com.mysql.jdbc.Driver"></property>
		<property name="jdbcUrl" value="jdbc:mysql:///test"></property>
	</bean>

9. spring的工厂

Spring提供了两种类型的IoC容器实现

  • BeanFactory:IOC容器的基本实现
    采用延时加载,第一次getBean时才会初始化Bean对象
  • ApplicationContext:提供了更多的高级特性,是BeanFactory的子接口
    BeanFactory是Spring框架的基础设施,面向Spring本身;ApplicationContext面向Spring框架的开发者
    几乎所有的应用场合都直接使用 ApplicationContext 而非底层的 BeanFactory .无论使用何种方式, 配置文件时相同的.

ApplicationContext

ApplicationContext  应用上下文  ,用来加载spring框架的配置文件,来构建spring的工厂对象,也称为Spring容器的上下文对象,也称为spring的容器

主要实现类

  • ClassPathXmlApplicationContext:从 类路径下加载配置文件
  • FileSystemXmlApplicationContext: 从文件系统中加载配置文件

ApplicationContext在初始化上下文时就是实例化所有的单例的Bean

10.Bean 之间的关系

  • 继承
    抽象Bean:abstract=“true”,不能被IoC实例化,只能用来被继承配置
    如果一个Bean的Class值没有被指定,那么这个Bean的abstract属性必须为true
    使用Bean的parent属性来制定继承哪一个Bean

  • 依赖
    通过depends-on 设置前置依赖的bean,依赖的bean会在当前bean实例化之前创建好。
    如果依赖多个bean 可以使用 , | 和 空格 来区分多个bean。

11. 配置Bean 的三种方法

  • 反射
  • 工厂实现
  • 注解

11.1工厂实现Bean的配置

11.1.1静态工厂实现

public class StaticFactory {
	private static Map<String, Person> persons=new HashMap<String,Person>();
	static {
		persons.put("tom", new Person("Tom"));
		persons.put("jack", new Person("Jack"));
	}	
	//静态工厂方法
	public static Person InstanceFactory(String name){
		return persons.get(name);
	}
}

//配置文件
<!-- 静态工厂方法配置Bean -->
<bean id="tom" class="com.yn.spring01.StaticFactory" factory-method="InstanceFactory">
	<constructor-arg value="tom"></constructor-arg>
</bean>

//测试
ApplicationContext ac=new ClassPathXmlApplicationContext("com/yn/spring01/beans.xml");
Person bean = (Person) ac.getBean("tom");
System.out.println(bean);

11.2 实例工厂实现

public class InstanceFactory {
	
	Map<String ,Person> map=null;
	
	public InstanceFactory(){
		
		map=new HashMap<String ,Person>();
		map.put("xixi", new Person("Xixixixi"));
		map.put("haha", new Person("Hahahahah"));
		
	}
	
	public Person getPerson(String name){
		return map.get(name);
	}

}

//配置文件
<!-- 实例工厂配置Bean -->
<bean id="instance" class="com.yn.spring01.InstanceFactory"></bean>
<bean id="xixi" factory-bean="instance" factory-method="getPerson">
	<constructor-arg value="xixi"></constructor-arg>
</bean>

//测试
Person bean2 = (Person) ac.getBean("xixi");
System.out.println(bean2);

11.1.3 FactoryBean

public class PersonFactoryBean implements FactoryBean<Person> {

	private String name;
	
	
	public void setName(String name) {
		this.name = name;
	}

	public Person getObject() throws Exception {
		// TODO Auto-generated method stub
		return new Person(name);
	}

	public Class<?> getObjectType() {
		// TODO Auto-generated method stub
		return Person.class;
	}

	public boolean isSingleton() {
		// TODO Auto-generated method stub
		return true;
	}

}


//配置文件
<!--  FactoryBean 配置bean实例-->
<bean id="p" class="com.yn.spring01.PersonFactoryBean">
	<property name="name" value="FactoryBean"></property>
</bean>

//测试
Person bean3 = (Person) ac.getBean("p");
System.out.println(bean3);

11.2 注解方式配置Bean

在使用注解时在之前的五个包里,还要加一个AOP包

在使用注解时,要在配置文件中开启扫描包

<!--   
	base-package 属性指定一个需要扫名的基类包,Spring容器会扫描这个基类包里及其子包中所有的的类
	当需要扫描多个包时,可以使用逗号隔开

	如果需要扫描特定的类,而非基类包下的所有类,可使用resource-Pattern 属性过滤特定的类
-->
<context:component-scan base-package="com" />

对于扫描的组件,spring有默认的命名策略:使用类名 第一个字母小写 也可以使用value属性标识组件

组件包裹 4 个

@Conponent 基本注解,标识一个受Springf IoC 容器管理的组件

@Respository 标识持久层

@Service 标识业务层

@Controller 标识控制层

组件装配

注入包裹 3 个

@AuthWired 自动装配具有兼容类型的单个Bean属性

@Resource 注解要求提供一个 Bean 名称的属性,若该属性为空,则自动采用标注处的变量或方法名作为 Bean 的名称

@Inject 和 @Autowired 注解一样也是按类型匹配注入的 Bean, 但没有 reqired 属性建议使用 @Autowired 注解

@AuthWired:可以使用在属性,set方法和构造器的前面

@Qualifier:提供了Bean的名称,Spring允许对方法的入参标注@Qualifier指定注入Bean的名称

12. spEl表达式

spring表达式语言 即 spEL:是一个运行时查询和操作对象图的强大表达式语言

使用#{}作为定界符  为bean属性动态赋值提供了便利



<property name="test" value="#{5}"/>
<property name="test" value="#{3.14}"/>
<property name="test" value="#{1e4}"/>
<property name="test" value="#{'哈哈'}"/>
<property name='test' value='#{"嘿嘿"}'/>

<!--引用其他bean对象,等价于ref属性。-->
<property name="pet" value="#{pet1}"></property>
<!--引用其他bean对象的属性。	-->
<property name="pet" value="#{pet1.petName}"></property>
<!--拿到方法的返回值。	-->
<property name="name" value="pet1.toString()"></property>
<!--链式调用。-->
<property name="name" value="pet1.toString().toUpperCase()"></property>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值