Spring学习02


Spring

轻量级(对比EJB)、解决方案、整合了很多的设计模式

设计模式

  • 面向对象设计中,解决特定问题的经典代码
  • 狭义上指:GOF四人定义的23中设计模式
工厂模式

通过工厂类创建对象
解耦,避免硬编码

核心API

ApplicationContext(工厂)
  • 用于对象的创建
  • 接口:屏蔽实现的差异(主要有两种实现)
  • 非Web环境:ClassPathXmlApplicationContext
  • Web环境:XmlWebApplicationContext(需要导入spring-webmvc)

在这里插入图片描述

  • ApplicationContext工厂对象占用大量内存(重量级资源):一个应用只会创建一个工厂对象
  • 线程安全的:多线程并发访问
ApplicationContext的方法

bean = component

  • getBean():有三个重载
  • getBeanDefinitionNames:获取bean的id值
  • getBeanNamesForType:指定类型的id值
  • containsBeanDefinition:是否存在id(只判断id)
  • containsBean:是否存在id或者name(判断id和name)
配置文件
  • 可以没有省略id,Spring会自动生成一个全限定名#0
  • id是唯一的,有命名的要求(XML的历史要求,如今已经不限制了)
  • name可以有多个值,使用,隔开(用得少)
  • containsBeanDefinitioncontainsBean有区别

注入(Injection)

解耦合

  • Set注入
  • 构造注入
Set注入
<bean class="com.tonkia.Person">
	<property name="id" value="1"/>
	<property name="name" value="tonkia"/>
</bean>
  • JDK内置类型
    • 8种基本类型 + String
    • 数组
    • Set
    • List
    • Map
    • Properties
  • 用户自定义类型
  • 复杂的JDK类型(Date):自定义类型转换器
p命名空间
<bean id="classRoom" class="com.tonkia.ClassRoom"/>

<bean class="com.tonkia.Person" p:id="1" p:name="tonkia" p:classroom-ref="classRoom"/>
构造注入
<bean class="com.tonkia.Customer">
	<constructor-arg>
	    <value>tonkia</value>
	</constructor-arg>
	<constructor-arg>
	    <value>12</value>
	</constructor-arg>
</bean>
  • 构造参数不同:通过<constructor-arg>的个数区分
  • 构造参数相同:指定type来区分

反转控制(IoC)

Inverse of Control

  • 控制:对于成员变量赋值的控制权
  • 反转控制:把对于成员变量赋值的控制权从代码中转移(反转)到Spring工厂和配置文件中完成
  • 底层实现:工厂设计模式
依赖注入(Dependency Injection,DI)

反转控制是一种概念,通过DI实现IoC

复杂对象

不能之间通过new方法创建的对象
例如:Connection、SqlSessionFactory

创建的三种方式
  1. FactoryBean接口
  2. 实例工厂
  3. 静态工厂
FactoryBean接口
  • 实现FactoryBean接口
public class TestFactoryBean implements FactoryBean<Person> {
    @Override
    public Person getObject() throws Exception {
        Person p =new Person();
        p.setClassroom(new ClassRoom());
        p.setName("fb");
        p.setId(100);
        return p;
    }

    @Override
    public Class<?> getObjectType() {
        return Person.class;
    }

    @Override
    public boolean isSingleton() {
        return false;
    }
}

  • 配置文件
<bean id="factoryBean" class="com.tonkia.TestFactoryBean"/>
  • 获取对象
    获取复杂对象
    applicationContext.getBean(“factoryBean”);
    获取FactoryBean对象
    applicationContext.getBean("&factoryBean");
实例工厂
  • 避免Spring侵入(实现FactoryBean接口)
  • 整合遗留系统
<bean id="factoryBean" class="com.tonkia.TestFactoryBean"/>

<bean id="person" factory-bean="factoryBean" factory-method="getObject"/>
静态工厂
<bean class="com.tonkia.StaticFactoryBean" factory-method="getObject"/>

在这里插入图片描述

控制Spring工厂创建次数

  • 节省内存空间
简单对象

scope

  • singleton(default)
  • prototype
复杂对象
  • FactoryBean:isSingleton方法返回值
  • 实例工厂、静态工厂:scope

对象生命周期

创建、存活、消亡

对象创建

singleton:默认容器创建的时候创建单例对象,除非指定lazy-init="true"
prototype:获取对象的时候创建对象

初始化阶段

创建完对象(属性注入)后,进行初始化
在初始化方法中进行资源的初始化
实现InitializingBean接口

public class ClassRoom implements InitializingBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        
    }
}

无侵入的方法:指定初始化方法

<bean class="com.tonkia.ClassRoom" init-method="init"/>

在这里插入图片描述

销毁阶段

发生在工厂关闭(显示close:applicationContext.close())的时候,进行资源释放回收
只适用于singleton,prototype不起作用

  • 实现DisposableBean
public class ClassRoom implements DisposableBean, InitializingBean {

    @Override
    public void afterPropertiesSet() throws Exception {

    }

    @Override
    public void destroy() throws Exception {

    }
}
  • 指定distory-method
<bean class="com.tonkia.ClassRoom" init-method="myInit" destroy-method="myDestory"/>
执行顺序
public class ClassRoom implements DisposableBean, InitializingBean {
    private String className;

    public void setClassName(String className) {
        System.out.println("ClassRoom.set");
        this.className = className;
    }

    public ClassRoom() {
        System.out.println("ClassRoom.constructor");
    }

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

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

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("ClassRoom.afterPropertiesSet");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("ClassRoom.destroy");
    }
}
<bean class="com.tonkia.ClassRoom" init-method="myInit" destroy-method="myDestory">
    <property name="className" value="math"/>
</bean>

在这里插入图片描述

配置文件参数化

<context:property-placeholder location="classpath:/config.properties"/>

自定义类型转换器

注入过程中将String类型转换为对应的类型
例如:将String转换为Date类型(Spring只提供了yyyy/MM/dd

  1. 实现Converter接口
public class MyConverter implements Converter<String, Date> {
    private SimpleDateFormat pattern = new SimpleDateFormat("yyyy-MM-dd");

    public void setPattern(String pattern) {
        this.pattern = new SimpleDateFormat(pattern);
    }

    @Override
    public Date convert(String s) {
        Date d = null;
        try {
            d = pattern.parse(s);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return d;
    }
}

  1. 在配置文件中注册
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="com.tonkia.MyConverter">
                <property name="pattern" value="yyyy-MM-dd"/>
            </bean>
        </set>
    </property>
</bean>

<bean class="com.tonkia.Product">
    <property name="id" value="1"></property>
    <property name="birthday" value="1996-10-03"></property>
</bean>

其中id值必须为conversionService

BeanPostProcessor

对Spring工厂创建的对象进行再加工
AOP底层实现

  • postProcessBeforeInitialization:set后init前
  • postProcessAfterInitialization:init后
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值