个人博客网:https://wushaopei.github.io/    (你想要这里多有)

一、对象的生命周期

1、IOC之Bean的生命周期

创建带有生命周期方法的bean

public class Person {

	private Integer id;
private Car car; public void init() {
System.out.println("Person被初始化了……");
} public void destroy() {
System.out.println("Person被销毁了");
}

配置信息:

        <!--
init-method="init" 表示初始化方法为init (在构造器调用之后就调用)
destroy-method="destroy" 表示销毁方法为destroy(在容器销毁的时候,就调用。只是单例有效)
-->
<bean id="personLife" class="com.webcode.pojo.Person" init-method="init" destroy-method="destroy">
<property name="id" value="10" />
</bean>

加载结果图解:

2、Bean的后置处理器BeanPostProcessor

bean的后置处理器可以在bean对象调用初始化方法之前和之后做一些工作。

如何创建一个后置处理器呢,只需要实现BeanPostProcessor接口

测试bean的后置处理器

public class MyBeanPostProcessor implements BeanPostProcessor {

	@Override
public Object postProcessAfterInitialization(Object bean, String id) throws BeansException {
System.out.println("初始化方法之后调用 bean=>" + bean + ", id=>" + id);
if ("personLife".equals(id)) {
Person person = (Person) bean;
person.setCar(new Car("你想啥!", "想干啥干啥"));
}
return bean;//一定要把bean返回
} @Override
public Object postProcessBeforeInitialization(Object bean, String id) throws BeansException {
System.out.println("初始化方法之前调用 bean=>" + bean + ", id=>" + id);
return bean;//一定要把bean返回
} }

配置信息:

        <!--
init-method="init" 表示初始化方法为init (在构造器调用之后就调用)
destroy-method="destroy" 表示销毁方法为destroy(在容器销毁的时候,就调用。只是单例有效)
-->
<bean id="personLife" class="com.webcode.pojo.Person" init-method="init" destroy-method="destroy">
<property name="id" value="10" />
</bean> <!-- 配置bean的后置处理器 -->
<bean class="com.webcode.postprocessor.MyBeanPostProcessor" />

测试代码:

	@Test
public void test3() throws Exception {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println( applicationContext.getBean("personLife") );
applicationContext.close();
}

工作流程图解:

二、Spring管理数据库连接池

前提:导入数据库连接池的jar包

1、Spring配置管理数据库连接池对象(重点)

创建 dataSource.xml 配置文件

配置bean

        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="root" />
<property name="password" value="root" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test" />
<property name="driverClass" value="com.mysql.jdbc.Driver" />
</bean>

2、Spring引入单独的jdbc.properties配置文件(重点)

PropertyPlaceholderConfigurer 

jdbc.properties配置文件:

jdbc.user=root
jdbc.password=root
jdbc.url=jdbc:mysql://localhost:3306/test
jdbc.driverClass=com.mysql.jdbc.Driver

容器配置文件:

        <!--
PropertyPlaceholderConfigurer专门用来加载属性配置文件
-->
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<!-- 你加载的文件路径在哪
classpath: 表示从类路径下加载
-->
<property name="location" value="classpath:jdbc.properties"/>
</bean> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="driverClass" value="${jdbc.driverClass}" />
</bean>

打印结果——图解:

3、使用context名称空间加载jdbc.properties配置文件(重点)

        <!-- 使用Context名称空间,加载jdbc.properties -->
<context:property-placeholder location="classpath:jdbc.properties"/> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />
<property name="jdbcUrl" value="${jdbc.url}" />
<property name="driverClass" value="${jdbc.driverClass}" />
</bean>

结果打印图解:

三、注解功能

1、注解配置Dao、Service、Controller组件

通过注解分别创建Dao、Service、Controller

Spring配置bean的常用注解有

  • @Controller   配置web层组件
  • @Service 配置业务层Service组件
  • @Repository 配置持久层Dao组件
  • @Component 配置除了web层,Service层,Dao层之外的其他组件bean对象
  • @Scope 配置作用域

导包:

commons-logging-1.1.3.jar
spring-aop-4.3.18.RELEASE.jar
spring-beans-4.3.18.RELEASE.jar
spring-context-4.3.18.RELEASE.jar
spring-core-4.3.18.RELEASE.jar
spring-expression-4.3.18.RELEASE.jar

工程:

/**
* @Component
* 等价于:
* <bean id="book" class="com.webcode.pojo.Book" />
*/
@Scope("prototype")//多例
//@Scope("singleton")//单例
@Component
public class Book {}

单例:

多例:

/**
* @Repository
* 等价于:
* <bean id="bookDao" class="com.webcode.dao.BookDao" />
*/
@Repository("bookDao")
public class BookDao {
}

/**
* @Controller
* 等价于:
* <bean id="bookServlet" class="com.webcode.servlet.BookServlet" />
*/
@Controller
public class BookServlet {}

/**
* @Service
* 等价于:
* <bean id="bookService" class="com.webcode.service.BookService" />
*/
@Service
public class BookService {}

测试的代码:

	@Test
public void test1() throws Exception {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
System.out.println( applicationContext.getBean("book") );
System.out.println( applicationContext.getBean("bookDao") );
System.out.println( applicationContext.getBean("bookService") );
System.out.println( applicationContext.getBean("bookServlet") );
}

流程分析:

2、指定扫描包时的过滤内容

使用context:include-filter指定扫描包时要包含的类

使用context:exclude-filter指定扫描包时不包含的类

<context:include-filter /> 设置包含的内容

注意:通常需要与use-default-filters属性配合使用才能够达到“仅包含某些组件”这样的效果。即:通过将use-default-filters属性设置为false,

<context:exclude-filter /> 设置排除的内容

类别

示例

说明

annotation

com.webcode.XxxAnnotation

过滤所有标注了XxxAnnotation的类。这个规则根据目标组件是否标注了指定类型的注解进行过滤

assignable

com.webcode.BaseXxx

过滤所有BaseXxx类的子类。这个规则根据目标组件是否是指定类型的子类的方式进行过滤。

aspectj

com.webcode.*Service+

所有类名是以Service结束的,或这样的类的子类。这个规则根据AspectJ表达式进行过滤。

regex

com\.webcode\.anno\.*

所有com.webcode.anno包下的类。这个规则根据正则表达式匹配到的类名进行过滤。

custom

com.webcode.XxxTypeFilter

使用XxxTypeFilter类通过编码的方式自定义过滤规则。该类必须实现org.springframework.core.type.filter.TypeFilter接口

applicationContext.xml 中配置的内容如下

<!-- use-default-filters="false" 设置取消默认包含规则 -->
<context:component-scan base-package="com.webcode" use-default-filters="false">
<!-- context:include-filter 设置包含的内容 -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
<!-- context:exclude-filter 设置排除的内容 -->
<context:exclude-filter type="assignable" expression="com.webcode.service.BookService"/>
</context:component-scan>

以上配置会包含所有@Service注解的类。排除com.webcode.service.BookService

<!--
配置包扫描。扫描指定包名下(和子包下所有的组件)
base-package 包名 use-default-filters="true" 默认扫描 @Repository,Service,Controller,Compoment
-->
<context:component-scan base-package="com.webcode" use-default-filters="false">
<!--
context:exclude-filter扫描时排除哪些内容
type 按哪个类型进行过滤
annotation按注解进行过滤
expression表达式
不要这个注解的org.springframework.stereotype.Repository组件对象
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
<context:exclude-filter type="assignable" expression="com.webcode.service.BookService"/>
-->
<!--
context:include-filter 自定义包含一定要组合use-default-filters="false" 一起使用。
-->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
<context:include-filter type="assignable" expression="com.webcode.service.BookService"/>
</context:component-scan>

3、使用注解@Autowired自动装配

使用@Autowired注解实现根据类型实现自动装配

@Autowired 注解 会自动的根据标注的对象类型在Spring容器中查找相对应的类。如果找到,就自动装配。

使用@Autowired注解,不需要get/set方法

@Service
public class BookService {
/**
* @Autowired注解可以实现自动注入<br/>
* 1 先按类型进行查找注入<br/>
* 2 如果找到多个,就按属性名做为id接着查找注入。<br/>
*/
@Autowired
private BookDao bookDao; @Override
public String toString() {
return "BookService [bookDao=" + bookDao + "]";
} }

4、多个同类型的bean如何自动装配

如果资源类型的bean不止一个,默认根据@Autowired注解标记的成员变量名作为id查找bean,进行装配★

/**
* @Repository
* 等价于:
* <bean id="bookDao" class="com.webcode.dao.BookDao" />
*/
@Repository("bookDao")
public class BookDao {
}
/**
* @Repository
* 等价于:
* <bean id="bookDao" class="com.webcode.dao.BookDao" />
*/
@Repository
public class BookDaoExt extends BookDao{
}

/**
* @Service 等价于:
* <bean id="bookService" class="com.webcode.service.BookService" />
*/
@Service
public class BookService {
/**
* @Autowired注解可以实现自动注入<br/>
* 1 先按类型进行查找注入<br/>
* 2 如果找到多个,就按属性名做为id接着查找注入。<br/>
*/
@Autowired
private BookDao bookDao; @Override
public String toString() {
return "BookService [bookDao=" + bookDao + "]";
}
}

打印图解:

5、使用@Qualifier装配指定id的bean对象

如果根据成员变量名作为id还是找不到bean,可以使用@Qualifier注解明确指定目标bean的id★

@Service
public class BookService {
/**
* @Autowired注解可以实现自动注入<br/>
* 1 先按类型进行查找注入<br/>
* 2 如果找到多个,就按属性名做为id接着查找注入。<br/>
* 3 如果没有找到要报错<br/>
* 4 @Qualifier("bookDao")限定你用什么做为id来进行查找注入<br/>
*/
@Autowired
@Qualifier("bookDaoExt")
private BookDao bookDao; @Override
public String toString() {
return "BookService [bookDao=" + bookDao + "]";
}
}

6、@Autowired注解的required属性作用

@Autowired注解的required属性指定某个属性允许不被设置

@Service
public class BookService {
/**
* @Autowired注解可以实现自动注入<br/>
* 1 先按类型进行查找注入<br/>
* 2 如果找到多个,就按属性名做为id接着查找注入。<br/>
* 3 如果没有找到要报错<br/>
* 4 @Qualifier("bookDao")限定你用什么做为id来进行查找注入<br/>
* 5 你可以修改@Autowired的required属性值为false,允许值为null<br/>
*/
@Autowired(required=false)
@Qualifier("bookDaoExt")
private BookDao bookDao; @Override
public String toString() {
return "BookService [bookDao=" + bookDao + "]";
}
}

7、@Autowired和@Qualifier在方法上的使用

在方法的形参位置使用@Qualifier注解

	/**
* @Autowired标注在方法上。那么对象创建的时候。会自动调用做初始化工作
*/
@Autowired(required=false)
public void abc(@Qualifier("bookDao1234") BookDao bookDaoExt12) {
System.out.println("abc执行了 --->>>" + bookDaoExt12);
}

8、泛型注入

测试泛型依赖注入

四、Spring的专有测试

@ContextConfiguration

@RunWith

  1. 导入spring-test-4.3.18.RELEASE.jar
  2. 配置@ContextConfiguration
  3. 配置@RunWith
//@ContextConfiguration(locations="classpath:applicationContext.xml")
// 告诉spring的扩展的测试,说,上哪里去找这个Spring容器的配置文件
@ContextConfiguration(locations="classpath:applicationContext.xml")
// 使用Spring扩展的运行类去跑测试
@RunWith(SpringJUnit4ClassRunner.class)
public class SpringTest2 { @Autowired
UserService userService;
@Autowired
BookService bookService; @Test
public void test() throws Exception {
userService.saveEntity(new User());
System.out.println("==================华丽的分隔线=================");
bookService.saveEntity(new Book());
} }2

Spring ( 三 ) Spring的Bean的装配与生命周期、专用测试的更多相关文章

  1. 五 Spring的配置:Bean的配置,生命周期和作用范围

    Bean相关的配置: <bean>标签的id和name的配置: id:使用了约束中的唯一约束,里面不能出现特殊字符 name:没有使用唯一约束,理论上可以重复,实际上开发不行,里面可以出现 ...

  2. Spring中Bean的作用域、生命周期

                                   Bean的作用域.生命周期 Bean的作用域 Spring 3中为Bean定义了5中作用域,分别为singleton(单例).protot ...

  3. Spring之Bean的作用域与生命周期

    在前面博客中提到容器启动获得BeanDefinition对象中有一个scope 属性.该属性控制着bean对象的作用域.本章节介绍Bean的作用域及生命周期,了解bean是怎么来的又怎么没的. 一.B ...

  4. 详解Spring中Bean的作用域与生命周期

    摘要:在利用Spring进行IOC配置时,关于bean的配置和使用一直都是比较重要的一部分,同时如何合理的使用和创建bean对象,也是小伙伴们在学习和使用Spring时需要注意的部分,所以这一篇文章我 ...

  5. bean的作用域和生命周期

    一.Bean作用域 二.生命周期 其中,这个类实现各种接口重写各种方法,会按bean的声明周期按序执行: 其中,自定义的初始化和自定义销毁的方法不是实现接口重写,而是成员方法,并且在装配bean即在x ...

  6. @Scope注解设置创建bean的方式和生命周期

    1.1.1            Scope注解创建bean的方式和生命周期 作用 Scope设置对象在spring容器(IOC容器)中的生命周期,也可以理解为对象在spring容器中的创建方式. 取 ...

  7. 三张图片详解Asp.Net 全生命周期

    用三张图片详解Asp.Net 全生命周期 下面我们使用三张图片解析ASP.net的整个生命周期,我总感觉使用图片更加的清楚的说明这种问题,所以使用的这样方式 说明: 1  第一张图片从全局说明从客户端 ...

  8. Spring三种实例化Bean的方法

    1.实例化bean的三种方法:(1) 构造器<!-- 体验1 --><bean id="personService" class="com.persia ...

  9. Spring MVC系列-(2) Bean的装配

    2. Bean的装配 Spring容器负责创建应用程序中的bean,并通过DI来协调对象之间的关系.Spring提供了三种主要的装配机制: XML显式配置: Java配置类进行显式配置: 隐式的bea ...

随机推荐

  1. 【Spark】SparkStreaming与flume进行整合

    文章目录 注意事项 SparkStreaming从flume中poll数据 步骤 一.开发flume配置文件 二.启动flume 三.开发sparkStreaming代码 1.创建maven工程,导入 ...

  2. 装完B就跑,这几个Linux指令真的Diǎo

    本文介绍一些有趣的指令,实用或者可以装逼,不妨自己也来试试看: 文章目录 1 故事的开局 2 杰哥的表演 2.1 sl 2.2 htop 2.3 gcp 2.4 hollywood 2.5 cmatr ...

  3. Power BI:社保、公积金增减

    本月和上月比较,社保.公积金有增减,拓展开来,每两个相邻月份比较,社保.公积金有增减. 数据放在SQL Server Express,有公司.姓名.分类.个人缴费金额.单位缴费金额.年月等字段,uni ...

  4. [hdu5351]找规律,大整数模板

    题意:f(1)="a",f(2)="b",f(i)=f(i-1)+f(i-2),"+"表示连接符.给定n,m,求f(n)的前m个字符的“ne ...

  5. ipad4密码忘记锁定了如何破解

    ipad4更新后被要求输入密码,但很长一段时间后忘记了,一直想不起来,也没有忘记密码的选项,以下是简单的破解方法. 注意:没有备份的资料是要被清空的 一.windows10系统,安装iTunes安装 ...

  6. 字符串匹配算法:Sunday算法

    背景 我们第一次接触字符串匹配,想到的肯定是直接用2个循环来遍历,这样代码虽然简单,但时间复杂度却是\(Ω(m*n)\),也就是达到了字符串匹配效率的下限.于是后来人经过研究,构造出了著名的KMP算法 ...

  7. noi7219 复杂的整数划分问题

    noi7219 复杂的整数划分问题 #include <bits/stdc++.h> using namespace std; ; int dp1[maxn][maxn], dp2[max ...

  8. 两圆相交求面积 hdu5120

    转载 两圆相交分如下集中情况:相离.相切.相交.包含. 设两圆圆心分别是O1和O2,半径分别是r1和r2,设d为两圆心距离.又因为两圆有大有小,我们设较小的圆是O1. 相离相切的面积为零,代码如下: ...

  9. 【MySQL】如何解决分库分表遇到的自增主键的问题?

    雪花算法 Redis生成主键

  10. 第二篇-用Flutter手撸一个抖音国内版,看看有多炫

    前言 继上一篇使用Flutter开发的抖音国际版 后再次撸一个国内版抖音,大部分功能已完成,主要是Flutter开发APP速度很爽,  先看下图 项目主要结构介绍 这次主要的改动在api.dart 及 ...