Spring学习(一)

Spring

Spring框架概述

  • Spring是轻量级的开源JavaEE框架,他可以降低企业应用开发中的复杂性。
  • Spring有两个核心组成部分,IOC和AOP
    • IOC:inversion of control ,控制反转。即将创建对象和属性注入的过程交给Spring来管理。
    • AOP:Aspect Oriented Programming,面向切面编程。可以在不修改源代码的基础上进行功能增强。
  • Spring特点
    • 方便解耦,简化开发
    • AOP编程支持
    • 方便程序测试
    • 方便与其他框架进行整合
    • 方便进行事务操作
    • 降低API开发难度

Spring入门程序

引入Spring所需依赖(即导入jar包后),即可以开始设计Spring框架的入门程序。
创建普通类User

public class User{
	public void add(){
		System.out.println("ADD方法");
	}
}

创建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标签用于User对象创建 -->
	<bean id="user" class="com.jarvis.bean.User"></bean>
</beans>

使用测试方法获取对象

@Test
public void test1(){
	//获取应用程序上下文对象
	ApplicationContext context = ClassPathXMLApplicationContext("bean.xml");
	//使用应用程序上下文对象获取Bean对象
	User user = context.getBean("user" , User.class);
	user.add();
}

IOC(控制反转)

  • 什么是IOC
    IOC是指控制反转,即将对象创建和对象之间的调用过程交给Spring来处理,这样能够显著的降低程序的耦合性(即不需要再其他类中使用new创建对象)
  • IOC底层原理
    IOC底层使用了XML解析技术、工厂原理和反射。
    • <bean id="" class=""></bean>,通过解析xml文件,来根据配置信息创建相应的工厂类
    • 通过工厂模式以及XML解析出的class属性值,通过反射的方法Class clazz = Class.forName(classValue)clazz.newInstance()创建目标对象
  • IOC的BeanFactory接口
    • IOC思想基于IOC容器完成,IOC容器就是对象工厂
    • Spring中提供两种IOC容器的实现方式(两个接口)
      • BeanFactory:IOC容器的基本实现,是Spring内部的使用接口,不提供开发人员使用。而且在加载xml配置文件时不会根据配置信息创建对象,只有在获取(使用)对象时才会创建对象(类似于懒汉式单例模式)
      • ApplicationContext:应用程序上下文接口,是BeanFactory的子接口,功能更加强大,一般由开发人员使用。在加载配置文件时就会根据配置信息创建对象(类似于饿汉式单例模式)
      • ApplicationContext接口的实现类有二:
        • FileSystemXMLApplicationContext:根据盘路径解析XML配置文件
        • ClassPathXMLApplicationContext:根据类路径解析XML配置文件

IOC的Bean管理

  • Bean管理的概念
    Spring中Bean管理的概念为Spring框架完成Bean对象的创建以及属性注入。Bean管理有两种实现方式,一种是基于XML配置文件的方式,另一种是基于注解的方式。
  • 基于XML方式实现Bean管理
    • 创建Bean对象
      在xml文件中使用bean标签,如<bean id="" class="" ></bean>。其中id属性是唯一标识,用于给Bean对象创建唯一标识,也是获取(创建)Bean的标识;class属性用于指明对象的全路径。在创建对象时默认使用newInstance()无参构造方法。
    • 注入属性(DI,dependency injection,依赖注入,也即属性注入)
      输入属性有三种实现方式:
      • 使用类的set方法注入,即在bean标签中使用property标签进行属性注入:<property name="" value=""></prioperty>,name属性需要和类中对应属性一致。
      • 使用有参构造方法注入,即在bean标签中使用constructor-arg标签进行属性注入:<constructor-arg name="" value=""></constructor-arg>,name属性需要和类中有参构造方法中的参数一致
      • p名称空间注入,在xml文件中引入p名称空间<beans xmlns:p=""></beans>,随后既可以在bean标签中使用p属性进行属性注入:<bean p:name1="value" p:name2="value2"></bean>
    • 使用xml方式注入其他类型属性
      • 字面量
        (a) 注入null值:在property标签中加入null标签即可<property name=""></null></property>
        (b) 属性值中包含特殊字符:在property标签中使用CDATA标签即可
      • 外部bean
        当需要注入的属性是同xml文件中的外部bean时,可以在property标签中使用ref属性取代value属性,属性值为该外部bean的id值<property name="" ref="外部bean的id值"></property>
      • 内部bean
        当需要注入的属性是引用数据类型时,可以使用内部bean的方式,即在property标签内部使用bean标签
      • 级联赋值
    • 使用xml注入集合属性
      • 注入数组类型属性:可以在property标签内使用array标签来进行赋值<property name=""><array><value>数组项</value></array></property>
      • 注入list集合属性:和注入数组类似,将Array标签换为list标签即可
      • 注入map集合属性:在property标签中使用map标签,在map标签中使用entry标签表示键值对,key属性和value属性填充键值对
      • 在集合中设置对象类型值:在集合中如果集合项存在引用数据类型(即对象),可以使用外部bean的方式:<list><ref bean="外部bean的id值"></ref><list>
      • 把集合注入部分抽取出来,其中的数据信息可以供多个集合使用:
        在配置文件中引入util名称空间,这样就可以使用util标签。将集合中的数据项放置在util标签内即可:
<util:list id="list1">
	<value>数据项1</value>
	<value>数据项2</value>
	<value>数据项3</value>
</util>

<bean id="" class="">
	<property name="list" ref="list1">
	</property>
</bean>
  • FactoryBean
    Spring中的bean有两种:
    - 第一种是普通bean,即上文所说的普通的java类。这种类在xml配置文件中class属性配置的类型和对象创建返回的类型是一致的,因此被称为普通bean
    - 第二种是工厂bean,即FactoryBean。工厂Bean的特殊性在于在XML配置文件中class属性指向的是该工厂类Bean的全类名,而创建对象返回的结果却是该工厂类创建出的产品Bean。使用工厂Bean,需要创建一个集成FactoryBean接口的类,并将目标返回的对象类型放置到该接口的泛型中。实现该接口的getObject对象,即可获取到目标类对象。
public class MyBean implments FactoryBean<User>{
	@Override
	public User getObject() throws Exception{
		User user = new User();
		user.setName("jarvis");
		return user;
	}
}
//在xml文件中的配置为,只需要指向实现了工厂Bean接口的该类即可
<bean id="user" class="com.jarvis.bean.MyBean"></bean>

//在test测试使用时,可以发现返回的并不是MyBean类型,而是User类型
public void test(){
	ApplicationConetxt context = new ClassPathXMLApplicationContext("bean.xml");
	User user = context.getBean("user",User.class);
}
  • Bean的作用域
    在Spring中可以设置创建好的Bean实例是单例还是多例。在默认情况下,使用IOC创建出的Bean是单例对象,即无论创建多少个对象引用,指向的都是唯一一个对象。
    在bean标签中存在有scope属性,可以用于设置创建出的对象是单例还是多例:
    <bean id="" class="" scope="singleton"></bean>,singleton表示获取bean对象时会获得单例bean对象,prototype表示会获得多例对象。此外scope属性还有requestsession等值,表示在bean对象创建好后会保存在哪个域中。

  • bean的生命周期
    生命周期是指bean对象从对象创建到销毁的过程:

    • 构造器创建bean对象实例(使用无参构造方法)
    • 为bean对象进行属性注入(使用set方法等)
    • 调用bean对象的初始化方法(在bean标签中使用init-method属性设置
    • 实际使用时获取到bean对象,bean对象可以使用
    • 调用bean对象的销毁方法(在bean标签中使用destroy-method属性设置
class User{
	public User(){}

	public void initMethod(){}
	
	public void destoryMethod(){}
}
//在xml中配置
<bean id="" class="" init-method="initMethod" destory-method="destoryMethod"></bean>
  • bean的后置处理器
    其实bean的生命周期还存在后置处理器,用于统一对所有bean对象进行操作,故bean的生命周期为:
    • 构造器创建bean对象实例(使用无参构造方法)
    • 为bean对象进行属性注入(使用set方法等)
    • 把bean实例传送到bean后置处理器的postProcessorBeforeInitialization方法进行处理
    • 调用bean对象的初始化方法(在bean标签中使用init-method属性设置
    • 实际使用时获取到bean对象,bean对象可以使用
    • 调用bean对象的销毁方法(在bean标签中使用destroy-method属性设置
    • 把bean实例传送到bean后置处理器的postProcessorAfterInitialization方法进行处理
      添加后置处理器:创建BeanPostProcessor接口的实现类,并实现后置处理器的两个方法。而且需要在xml文件中设置该类的bean标签,来提交给Spring代理。
//实现beanPostProcessor接口
public class BeanPost() implments BeanPostProcessor{
	@Override
 	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
 		//执行后置处理器的操作
 		return bean;
 	}

	@Override
 	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
 		//执行后置处理器操作
 		return bean;
 	}
}

//在xml文件中进行配置
<bean id="beanPost" class="com.jarvis.bean.BeanPost"></bean>
这样就可以对同一xml文件中生命的bean对象统一执行该后置处理器的操作。
  • xml自动装配
    自动装配是指根据指定的装配规则,由Spring自动将匹配的属性值进行注入(注意,自动注入的需要在同一配置文件中声明的bean)。
    自动装配是由bean标签中的autowire属性实现的,有byName和byType两个值
    • byName:根据属性名称注入,注入值bean的id和类属性名称一致
    • byType:根据属性类型注入,注入bean的class类型和类属性的类型一致
<bean id="emp" class="com.jarvis.beanEmp" autowire="byType">
	<!-- <property name="" ref="dept"></property> -->
</bean>
<bean id="dept" class="com.jarvis.bean.Dept"></bean>
  • 外部属性文件
    xml配置文件也可以引入外部属性文件作为配置信息进行配置,这里以配置JDBC数据库连接为例:
    • 直接配置数据库信息
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
	<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
	<property name="url" value="jdbc:mysql://localhost:3306/book"></property>
	<property name="username" value="root"></property>
	<property name="password" value="root"></property>
</bean>
    • 引入外部文件配置:首先需要引入context名称空间,随后就可以使用context标签引入外部文件,并使用Spring表达式配置数据信息
外部文件信息
prop.dirverClassName=com.mysql.jdbc.Driver
prop.url=http://localhost:3306/book
prop.username=root
prop.password=root
引入外部文件
<context:property-placeholder location="classpath:jdbc.properties">
使用外部文件
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
	<property name="driverClassName" value="${prop.username}"></property>
	<property name="url" value="http:localhost:3306/book"></property>
	<property name="username" value="root"></property>
	<property name="password" value="root"></property>
</bean>
  • 基于注解方式实现Bean管理
    注解是代码的特殊标记,可以用于类、方法、属性甚至参数。使用注解,可以简化xml甚至代替xml配置文件
    Spring中针对Bean管理创建对象提供了四个注解,这四个注解的功能一致,都可以用于Bean对象的创建
    • @Component(value=""):比较普通的注解,可用于所有bean对象的创建(valkue相当于xml文件中bean标签的id属性)
    • @Service(value=""):用于Service层
    • @Controller(value=""):推荐用于Web层
    • @Repository(value=""):推荐用于DAO层
  • 基于注解实现bean对象的创建
    使用注解创建Bean对象,需要引入AOP依赖。此外,还要开启组件扫描,也即告知Spring,那些组件(包中的类)上存在注解,需要Spring来创建Bean对象。随后创建类并在类上添加注解即可。可以使用xml文件来进行组件扫描:
<context:component-scan base-package="需要扫描的组件包"></context:component-scan>
注意:组件扫描还可以对细节进行配置
use-default-filter属性:表示是否使用默认filter,默认为true
context:include-filter和context:exclude-filter标签可以设置指定过滤器扫描或者忽略指定的组件
<context:component-scan base-package="com.jarvis" use-default-filter="false"></context:component-scan>
//表示自定义的过滤器会只扫描带有该注解的类
<conetxt:include-filter type="annotation" expression="org.springframework.stereotype.Controller"></conetxt:include-filter>
//表示自定义的过滤器会忽略带有该注解的类
<conetxt:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"></conetxt:include-filter>
  • 基于注解的方式实现属性注入
    对于使用注解方式实现属性注入存在四个注解以供使用
    • @Autowired:根据属性类型进行自动装配
    • @Qualifier:根据属性名称自动装配,该注解通常与Autowired一同使用
    • @Resource:可以实现根据属性类型或者名称自动装配(在javax包中声明,作为java的扩展内容存在,因此Spring一般不推荐使用)
    • @Value:用于注入基本数据类型的属性
@Component
public class User{
	@Value(value="小明")
	private String name;
	@Value(value="123456")
	private Integer id;
	//@Autowired      ---------------------------- 表示会根据类型注入,前提是该类需要由Spring实现自动创建
	//@Qualifier(value="dept")      -------------- 表示会根据名称注入
	//@Resource      ----------------------------- 表示会根据类型注入
	//@Resource(value="dept")      --------------- 表示会根据名称注入
	private Dept department;
}
  • 完全注解开发
    由上文可知,使用注解来进行Bean管理需要开启组件扫描,而组件扫描需要以xml文件的形式实现。因此想要实现完全注解开发,只需要创建一个配置类代替xml文件开启组件扫描即可:
@Configuration    //表示该类是用作配置类代替配置文件存在的
@ComponentScan(basePackages="com.jarvis")
public class ConfigurationClass{}
    在使用时只需要通过注解获取应用程序上下文对象即可:
public void test(){
	ApplicationContext context = AnnotationConfigApplicationContext(ConfigurationClass.class);
	context.getBean(...);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值