Spring入门

1_Spring_概念介绍_了解

 

Spring是分层的全栈式的轻量级开发框架,以IOC和AOP为核心,官网是https://spring.io

Spring优势

1 方便解耦,简化开发

Spring通过容器,将对象的创建从代码中剥离出来,交给Spring控制,避免直接编码造成模块之间的耦合度高,用户也不必自己编码处理对象的单例和多例控制,主要关注接口功能即可,不用关注具体使用哪个实现类和实现细节问题

2 AOP切面编程

AOP切面编程是程序设计的一种概念,Spring对该概念实现的比较好,通过切面编程我们可以在不修改原有代码的情况下实现功能的增加,通常用于 事务控制,日志记录,性能检测,权限控制等等

3 声明式事务

事务的控制可以托管给Spring,我们通过注解或者配置文件声明事务的处理方式即可,不用我们自己去编码处理

 

4 整合JUNIT,方便测试

spring整合JUNIT单元测试,对于项目的功能都可以进行轻松快速的测试,便于我们调试程序

5方便整合各种优秀的框架

SSM> Spring+SpringMVC +MyBatis

SSH> Spring+Hibernate +Strust

6 丰富的功能封装

spring对JAVAEE(JDBC ,JAVAMail,)都进行了一系列的封装,简化我们对于API的使用,提高程序的开发效率

7 规范的源码学习样本

spring的源码设计巧妙,结构清晰,大量使用了设计模式,是java代码规范编写的典范,也是高级程序员面试中经常会问到的源码

Spring的体系结构

 1. Data Access/Integration(数据访问/集成)

数据访问/集成层包括 JDBC、ORM、OXM、JMS 和 Transactions 模块,具体介绍如下。

  • JDBC 模块:提供了一个 JDBC 的抽象层,大幅度减少了在开发过程中对数据库操作的编码。
  • ORM 模块:对流行的对象关系映射 API,包括 JPA、JDO、Hibernate和 iBatis 提供了的集成层。
  • OXM 模块:提供了一个支持对象/XML 映射的抽象层实现,如 JAXB、Castor、XMLBeans、JiBX 和 XStream。
  • JMS 模块:指 Java消息服务,包含的功能为生产和消费的信息。
  • Transactions 事务模块:支持编程和声明式事务管理实现特殊接口类,并为所有的 POJO。

2. Web 模块

Spring 的 Web 层包括 Web、Servlet、Struts 和 Portlet 组件,具体介绍如下。

  • Web 模块:提供了基本的 Web 开发集成特性,例如多文件上传功能、使用的 Servlet 监听器的 IoC 容器初始化以及 Web 应用上下文。
  • Servlet模块:包括 Spring 模型—视图—控制器(MVC)实现 Web 应用程序。
  • Struts 模块:包含支持类内的 Spring 应用程序,集成了经典的 Struts Web 层。
  • Portlet 模块:提供了在 Portlet 环境中使用 MV C实现,类似 Web-Servlet 模块的功能。

3. Core Container(核心容器)

Spring 的核心容器是其他模块建立的基础,由 Beans 模块、Core 核心模块、Context 上下文模块和 Expression Language 表达式语言模块组成,具体介绍如下。

  • Beans 模块:提供了 BeanFactory,是工厂模式的经典实现,Spring 将管理对象称为 Bean。
  • Core 核心模块:提供了 Spring 框架的基本组成部分,包括 IoC 和 DI 功能。
  • Context 上下文模块:建立在核心和 Beans 模块的基础之上,它是访问定义和配置任何对象的媒介。ApplicationContext 接口是上下文模块的焦点。
  • Expression Language 模块:是运行时查询和操作对象图的强大的表达式语言。

4. 其他模块

Spring的其他模块还有 AOP、Aspects、Instrumentation 以及 Test 模块,具体介绍如下。

  • AOP 模块:提供了面向切面编程实现,允许定义方法拦截器和切入点,将代码按照功能进行分离,以降低耦合性。
  • Aspects 模块:提供与 AspectJ 的集成,是一个功能强大且成熟的面向切面编程(AOP)框架。
  • Instrumentation 模块:提供了类工具的支持和类加载器的实现,可以在特定的应用服务器中使用。
  • Test 模块:支持 Spring 组件,使用 JUnit 或 TestNG 框架的测试。

2_Spring_IOC概念引入_重要

 

简单的说就是,创建对象的权利,或者是控制的位置,由JAVA代码转移到spring容器,由spring的容器控制对象的创建,就是控制反转,spring创建对象时,会读取配置文件中的信息,然后使用反射给我们创建好对象之后在容器中存储起来,当我们需要某个对象时,通过id获取对象即可,不需要我们自己去new.

一句话:创建对象交给容器

Spring解耦合的原理

 

创建maven项目,设置maven

先创建一个空项目

名字可以是spring_all

在项目下创建模块 名字可以是spring_test_01

pom.xml中导入spring依赖

  1. <dependencies>
  2. <dependency>
  3. <groupId>springframework</groupId>
  4. <artifactId>spring-core</artifactId>
  5. <version>3.5</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>springframework</groupId>
  9. <artifactId>spring-beans</artifactId>
  10. <version>3.5</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>springframework</groupId>
  14. <artifactId>spring-context</artifactId>
  15. <version>3.5</version>
  16. </dependency>
  17. <dependency>
  18. <groupId>springframework</groupId>
  19. <artifactId>spring-expression</artifactId>
  20. <version>3.5</version>
  21. </dependency>
  22. </dependencies>

四个依赖介绍

spring-context      上下文,容器

spring-beans         创建对象

spring-core            核心jar

spring-expression 表达式jar

 

但是事实上,我们导入spring-context的时候,会自动导入其他依赖的jar,自动进行了依赖传递

所以,导入一个spring-context 依赖也可以

 

依赖传递关系图如下

 

 

为了方便测试,我们导入Junit测试依赖

  1. <dependency>
  2. <groupId>junit</groupId>
  3. <artifactId>junit</artifactId>
  4. <version>13.1</version>
  5. <scope>test</scope>
  6. </dependency>

 

在项目中定义一个接口和实现类

EmpDao接口和实现类

 

接口中定义一个方法并在实现类中实现

 

接口

 

 

实现类

 

 

 

在spring配置容器中的对象

创建spring配置文件

 

 

文件名没有明确要求,暂时可以叫spring

 

 

在spring.xml中配置一个需要由容器初始化的对象

 

 

 

 

 

测试通过容器获取对象

 

 

3_Spring_IOC原理分析_重要

IOC底层原理

 

1 XML解析技术读取配置文件

  1. <bean id=”empDao”class=”com.msb.dao.impl.EmpDaoImpl”></bean>

将上面的信息读取进入程序  对象的ID ,一个是对象的类的全路径名

 

 

 

2 反射技术实例化对象,放到容器中

      获得类的字节码

Class clazz =Class.forName(“com.msb.dao.impl.EmpDaoImpl”)

通过字节码实例化对象

Object obj  = clazz.newInstance();

将对象放到一个map集合中

map.put(“empDao”,obj)

 

 

 

3工厂模式返回Bean对象 getBean方法

public Object getBean(String name){

Object obj =map.get(name);

return obj;

}

IOC接口

BeanFactory            接口: IOC容器基本功能接口,是spring内部使用的接口,我们在处理业务时一般不直接使用该接口

ApplicationContext 接口: BeanFactory的子接口,提供更多更强大的功能,研发人员一般使用的接口

 

 

 

 

 

 

 

 

 

 

 

 

 

4_Spring_XML方式实现DI

spring中的Bean的管理:

Bean(汉译咖啡豆). 又称JAVABean.其实就是JAVA程序程序中的一个个对象,所以Bean的管理其实就是spring对于JAVA程序中的对象的管理

 

 

管理的内容是什么

 

1 对象的创建   IOC

IOC   叫做控制反转,就是Spring给我们创建对象,然后我们直接用,不用自己NEW,前面已经解释过

IOC处理的是对象如何创建的问题

 

2 属性的赋值   DI

DI    Dependency Injection,即“依赖注入” 就是创建属性时给对象属性赋值

对象功能的实现往往要依赖属性的值,那么给对象属性赋值就可以说成是依赖注入

由于对象属性不仅仅是基本数据类型,还可能是其他类,或者引用类型

那么依赖注入将会把更多的对象之间的关系整理到一起,可以行程一个庞大的依赖关系

DI处理的是对象的属性赋值和互相依赖的关系

 

 

spring给我们提供了两种关于bean的方式

 

1 基于XML方式的Bean管理

 

2 基于注解方式的Bean管理

 

 

创建新的模块并导入以下依赖

 

依赖

  1. <dependency>
  2. <groupId>springframework</groupId>
  3. <artifactId>spring-context</artifactId>
  4. <version>3.5</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>junit</groupId>
  8. <artifactId>junit</artifactId>
  9. <version>13.1</version>
  10. <scope>test</scope>
  11. </dependency>

 

创建spring配置文件,一般spring的配置文件很多人约定俗称为application****.xml

 

 

准备一个要实例化的类

  1. publicclass User {
  2. private Integer userid;
  3. private String username;
  4. private String password;
  5. @Override
  6. public String toString() {
  7. return “User{” +
  8. “userid=” + userid +
  9. “, username='” + username + ‘\” +
  10. “, password='” + password + ‘\” +
  11. ‘}’;
  12. }
  13. public User() {
  14. out.println(“noArgConstructor”);
  15. }
  16. public User(Integer userid, String username, String password) {
  17. out.println(“allArgConstructor”);
  18. this.userid = userid;
  19. this.username = username;
  20. this.password = password;
  21. }
  22. public void setUserid(Integer userid) {
  23. out.println(“setUserid”);
  24. this.userid = userid;
  25. }
  26. public void setUsername(String username) {
  27. out.println(“setUsername”);
  28. this.username = username;
  29. }
  30. public void setPassword(String password) {
  31. out.println(“setpassword”);
  32. this.password = password;
  33. }
  34. }

IOC创建对象

通过无参构造方法构造对象

  1. <bean id=”user1″class=”com.msb.bean.User”></bean>

<bean> 标签的常见属性

  1. <bean id=”user1″class=”com.msb.bean.User” name=”user1″ scope=”prototype” lazy-init=”true” ></bean>

id    对象的id

class 类的全路径名

name 和id类似,一般不用

scope 控制对象单例多例和使用范围

singleton作用域(scope 默认值), Spring IOC容器中只会存在一个共享的bean实例

prototype作用域部署的bean,每一次获取都会产生一个新的bean实例,相当与一个new的操作

request表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效

session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效

global session作用域类似于标准的HTTP Session作用域,不过它仅仅在基于portlet的web应用中才有意义

lazy-init 懒加载 调用getBean的时候再去实例化对象

DI给对象属性赋值

1 通过set方法给对象属性赋值

  1. <!–property 就是在使用set方法实现依赖注入–>
  2. <bean id=”user1″ class=”com.msb.bean.User”>
  3. <property name=”userid” value=”1″></property>
  4. <property name=”username” value=”张三”></property>
  5. <property name=”password” value=”abcdefg”></property>
  6. </bean>

 

2 通过有参构造给对象属性赋值

  1. <!–
  2. constructor-arg 就是在使用构造方法实现依赖注入
  3. constructor-arg 的个数必须和某个构造方法的参数个数向对应
  4. name指的是参数名
  5. index指的是参数的索引
  6. value指的是参数值
  7. –>
  8. <bean id=”user2″ class=”com.msb.bean.User”>
  9. <constructor-arg name=”userid” value=”2″></constructor-arg>
  10. <constructor-arg name=”username” value=”小明”></constructor-arg>
  11. <constructor-arg name=”password” value=”123456789″></constructor-arg>
  12. </bean>
  13. <bean id=”user3″ class=”com.msb.bean.User”>
  14. <constructor-arg index=”0″  value=”3″></constructor-arg>
  15. <constructor-arg index=”1″  value=”小黑”></constructor-arg>
  16. <constructor-arg index=”2″  value=”987654321″></constructor-arg>
  17. </bean>

 

3 通过p名称空间和c名称空间给对象属性赋值

添加约束

  1. <?xml version=”1.0″encoding=”UTF-8″?>
  2. <beans xmlns=”http://www.springframework.org/schema/beans”
  3. xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
  4. xmlns:p=”http://www.springframework.org/schema/p”
  5. xmlns:c=”http://www.springframework.org/schema/c”
  6. xsi:schemaLocation=”http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd”>

配置对象

  1. <!–p名称空间,就是对property的简化处理–>
  2. <bean id=”user4″ class=”com.msb.bean.User” p:userid=”4″ p:username=”小东” p:password=”111111″ ></bean>
  3. <!–c名称空间,就是对constructor-arg的简化–>
  4. <bean id=”user5″ class=”com.msb.bean.User” c:userid=”5″ c:username=”小西” c:password=”222222″ ></bean>

 

测试代码

  1. public class Test1 {
  2. @Test
  3. public void testGetBean(){
  4. ApplicationContext context =new ClassPathXmlApplicationContext(“applicationContext.xml”);
  5. User user1 = context.getBean(“user1”, User.class);
  6. User user2 = context.getBean(“user2”, User.class);
  7. User user3 = context.getBean(“user3”, User.class);
  8. User user4 = context.getBean(“user4”, User.class);
  9. User user5 = context.getBean(“user5”, User.class);
  10. out.println(user1);
  11. out.println(user2);
  12. out.println(user3);
  13. out.println(user4);
  14. out.println(user5);
  15. }
  16. }

 

 

 

 

4 注入空值和特殊符号

  1. <bean id=”user1″ class=”com.msb.bean.User”>
  2. <!–null值–>
  3. <property name=”userid”>
  4. <null></null>
  5. </property>
  6. <!–特殊符号 转译字符 < <  >>  & &     –>
  7. <property name=”username” value=”&xiaoming<>”></property>
  8. <!– 特殊符号  <![CDATA[内容]]>  –>
  9. <property name=”password”>
  10. <value><![CDATA[&<123456>]]></value>
  11. </property>
  12. </bean>

 

 

5 关于bean引用

 

实体类

  1. packagemsb.bean;
  2. importutil.Date;
  3. /**
  4. * @Author: Ma HaiYang
  5. * @Description: MircoMessage:Mark_7001
  6. */
  7. publicclass Mouse {
  8. private String name;
  9. private Date birthdate;
  10. @Override
  11. public String toString() {
  12. return “Mouse{” +
  13. “name='” + name + ‘\” +
  14. “, birthdate=” + birthdate +
  15. ‘}’;
  16. }
  17. public Mouse() {
  18. }
  19. public Mouse(String name, Date birthdate) {
  20. this.name = name;
  21. this.birthdate = birthdate;
  22. }
  23. public String getName() {
  24. return name;
  25. }
  26. public void setName(String name) {
  27. this.name = name;
  28. }
  29. public Date getBirthdate() {
  30. return birthdate;
  31. }
  32. public void setBirthdate(Date birthdate) {
  33. this.birthdate = birthdate;
  34. }
  35. }
  36. packagemsb.bean;
  37. /**
  38. * @Author: Ma HaiYang
  39. * @Description: MircoMessage:Mark_7001
  40. */
  41. publicclass Cat {
  42. private String name;
  43. private Mouse mouse1;
  44. @Override
  45. public String toString() {
  46. return “Cat{” +
  47. “name='” + name + ‘\” +
  48. “, mouse1=” + mouse1 +
  49. ‘}’;
  50. }
  51. public Cat() {
  52. }
  53. public Cat(String name, Mouse mouse1) {
  54. this.name = name;
  55. this.mouse1 = mouse1;
  56. }
  57. public String getName() {
  58. return name;
  59. }
  60. public void setName(String name) {
  61. this.name = name;
  62. }
  63. public Mouse getMouse1() {
  64. return mouse1;
  65. }
  66. public void setMouse1(Mouse mouse1) {
  67. this.mouse1 = mouse1;
  68. }
  69. }

 

xml 配置

  1. <!–告诉容器准备一个Date对象–>
  2. <bean id=”date1″ class=”java.util.Date”></bean>
  3. <bean id=”mouse1″ class=”com.msb.bean.Mouse”>
  4. <property name=”name” value=”Jerry”></property>
  5. <!–bean引用引用外部bean–>
  6. <property name=”birthdate” ref=”date1″></property>
  7. </bean>
  8. <bean id=”cat1″ class=”com.msb.bean.Cat”>
  9. <property name=”name” value=”Tom”></property>
  10. <!–引用内部bean–>
  11. <property name=”mouse1″ >
  12. <bean class=”com.msb.bean.Mouse”>
  13. <property name=”name” value=”Jerry2″></property>
  14. <property name=”birthdate”>
  15. <bean class=”java.util.Date”></bean>
  16. </property>
  17. </bean>
  18. </property>
  19. </bean>
  20. <bean id=”mouse2″ class=”com.msb.bean.Mouse”></bean>
  21. <bean id=”cat2″ class=”com.msb.bean.Cat”>
  22. <property name=”name” value=”Tom2″></property>
  23. <!–级联引入bean–>
  24. <property name=”mouse1″ ref=”mouse2″></property>
  25. <!–用反射调用get*** 方法,获得对象之后,再赋值–>
  26. <property name=”mouse1.name” value=”Jerry3″></property>
  27. <property name=”mouse1.birthdate”>
  28. <bean class=”java.util.Date”></bean>
  29. </property>
  30. </bean>

 

6 关于集合注入

实体类

  1. packagemsb.bean;
  2. /**
  3. * @Author: Ma HaiYang
  4. * @Description: MircoMessage:Mark_7001
  5. */
  6. publicclass Book {
  7. private String bname;
  8. private String author;
  9. @Override
  10. public String toString() {
  11. return “Book{” +
  12. “bname='” + bname + ‘\” +
  13. “, author='” + author + ‘\” +
  14. ‘}’;
  15. }
  16. public Book() {
  17. }
  18. public Book(String bname, String author) {
  19. this.bname = bname;
  20. this.author = author;
  21. }
  22. public String getBname() {
  23. return bname;
  24. }
  25. public void setBname(String bname) {
  26. this.bname = bname;
  27. }
  28. public String getAuthor() {
  29. return author;
  30. }
  31. public void setAuthor(String author) {
  32. this.author = author;
  33. }
  34. }
  35. packagemsb.bean;
  36. importutil.Arrays;
  37. importutil.List;
  38. importutil.Map;
  39. importutil.Set;
  40. /**
  41. * @Author: Ma HaiYang
  42. * @Description: MircoMessage:Mark_7001
  43. */
  44. publicclass Student {
  45. private String[] books;
  46. private Set<String> bookSet;
  47. private List<String> bookList;
  48. private Map<String,String> bookMap;
  49. private List<Book> bookList2;
  50. @Override
  51. public String toString() {
  52. return “Student{” +
  53. “books=” + Arrays.toString(books) +
  54. “, bookSet=” + bookSet +
  55. “, bookList=” + bookList +
  56. “, bookMap=” + bookMap +
  57. “, bookList2=” + bookList2 +
  58. ‘}’;
  59. }
  60. public String[] getBooks() {
  61. return books;
  62. }
  63. public void setBooks(String[] books) {
  64. this.books = books;
  65. }
  66. public Set<String> getBookSet() {
  67. return bookSet;
  68. }
  69. public void setBookSet(Set<String> bookSet) {
  70. this.bookSet = bookSet;
  71. }
  72. public List<String> getBookList() {
  73. return bookList;
  74. }
  75. public void setBookList(List<String> bookList) {
  76. this.bookList = bookList;
  77. }
  78. public Map<String, String> getBookMap() {
  79. return bookMap;
  80. }
  81. public void setBookMap(Map<String, String> bookMap) {
  82. this.bookMap = bookMap;
  83. }
  84. public List<Book> getBookList2() {
  85. return bookList2;
  86. }
  87. public void setBookList2(List<Book> bookList2) {
  88. this.bookList2 = bookList2;
  89. }
  90. public Student() {
  91. }
  92. public Student(String[] books, Set<String> bookSet, List<String> bookList, Map<String, String> bookMap, List<Book> bookList2) {
  93. this.books = books;
  94. this.bookSet = bookSet;
  95. this.bookList = bookList;
  96. this.bookMap = bookMap;
  97. this.bookList2 = bookList2;
  98. }
  99. }

 

配置文件

  1. <?xml version=”1.0″encoding=”UTF-8″?>
  2. <beansxmlns=”http://www.springframework.org/schema/beans”
  3. xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
  4. xmlns:p=”http://www.springframework.org/schema/p”
  5. xmlns:c=”http://www.springframework.org/schema/c”
  6.  xmlns:util=”http://www.springframework.org/schema/util”
  7. xsi:schemaLocation=”
  8. http://www.springframework.org/schema/beans
  9. http://www.springframework.org/schema/beans/spring-beans.xsd
  10. http://www.springframework.org/schema/util
  11. http://www.springframework.org/schema/util/spring-util.xsd
  12. “>
  13. <!–定义公共集合–>
  14. <util:list id=”outerbookList”>
  15. <!–声明多个Book对象–>
  16. <bean id=”b1″ class=”com.msb.bean.Book” p:bname=”JAVA” p:author=”马士兵”></bean>
  17. <bean id=”b2″ class=”com.msb.bean.Book” p:bname=”Go” p:author=”马士兵”></bean>
  18. <bean id=”b3″ class=”com.msb.bean.Book” p:bname=”JVM” p:author=”马士兵”></bean>
  19. </util:list>
  20. <bean id=”student1″ class=”com.msb.bean.Student”>
  21. <!–数组属性注入–>
  22. <property name=”books”>
  23. <array>
  24. <value>JAVA</value>
  25. <value>MySQL</value>
  26. <value>Spring</value>
  27. </array>
  28. </property>
  29. <!–set集合注入–>
  30. <property name=”bookSet”>
  31. <set>
  32. <value>JAVA</value>
  33. <value>MySQL</value>
  34. <value>Spring</value>
  35. </set>
  36. </property>
  37. <!–list集合注入–>
  38. <property name=”bookList”>
  39. <list>
  40. <value>JAVA</value>
  41. <value>MySQL</value>
  42. <value>Spring</value>
  43. </list>
  44. </property>
  45. <!–map集合注入–>
  46. <property name=”bookMap”>
  47. <map>
  48. <entry key=”JAVA” value=”马士兵”></entry>
  49. <entry key=”Go” value=”马士兵”></entry>
  50. <entry key=”JVM” value=”马士兵”></entry>
  51. </map>
  52. </property>
  53. <!–List对象集合注入–>
  54. <property name=”bookList2″ ref=”outerbookList”></property>
  55. </bean>
  56. </beans>

7 工厂方式获取bean

特点 : bean标签中定义的class类不是返回的对象的类,而是生产该对象的工厂

工厂模式:GOF 设计模式

spring中给我们定义好了一个工厂接口,可以生产对象的接口,我们可以通过工厂来获取bean

 

定义工厂对象 实现 FactoryBean接口

  1. packagemsb.bean;
  2. importspringframework.beans.factory.FactoryBean;
  3. /**
  4. * @Author: Ma HaiYang
  5. * @Description: MircoMessage:Mark_7001
  6. */
  7. publicclass BookFactory implements FactoryBean<Book> {
  8. @Override
  9. public Book getObject() throws Exception {
  10. Book book=new Book();
  11. setBname(“JAVA”);
  12. setAuthor(“马士兵”);
  13. return book;
  14. }
  15. @Override
  16. public Class<?> getObjectType() {
  17. return null;
  18. }
  19. }

配置文件

  1. <bean id=”book”class=”msb.bean.BookFactory”></bean>

测试代码

  1. @Test
  2. public void testGetBean(){
  3. ApplicationContext applicationContext=new ClassPathXmlApplicationContext(“applicationContext5.xml”);
  4.  Book book = applicationContext.getBean(“book”, class);
  5. out.println(book);
  6. }

 

 

 

5_Spring_Bean的生命周期

 

bean从创建到销毁经历的各个阶段以及每个阶段所调用的方法

1 通过构造器创建bean实例           执行构造器

2 为bean属性赋值                         执行set方法

3 初始化bean                                调用bean的初始化方法,需要配置指定调用的方法

4 bean的获取                                容器对象 getBean方法

5 容器关闭销毁bean                      调用销毁方法,需要配置指定调用的方法

 

测试生命周期

准备bean

  1. package com.msb.bean;
  2. /**
  3. * @Author: Ma HaiYang
  4. * @Description: MircoMessage:Mark_7001
  5. */
  6. publicclass User {
  7. private Integer userid;
  8. private String username;
  9. private String password;
  10. public void initUser(){
  11. out.println(“第三步:User初始化”);
  12. }
  13. public User() {
  14. out.println(“第一步:User构造”);
  15. }
  16. public void destoryUser(){
  17. out.println(“第五步:User销毁”);
  18. }
  19. @Override
  20. public String toString() {
  21. return “User{” +
  22. “userid=” + userid +
  23. “, username='” + username + ‘\” +
  24. “, password='” + password + ‘\” +
  25. ‘}’;
  26. }
  27. public User(Integer userid, String username, String password) {
  28. this.userid = userid;
  29. this.username = username;
  30. this.password = password;
  31. }
  32. public void setUserid(Integer userid) {
  33. out.println(“setUserid”);
  34. this.userid = userid;
  35. }
  36. public void setUsername(String username) {
  37. out.println(“第二步:User属性赋值”);
  38. this.username = username;
  39. }
  40. public void setPassword(String password) {
  41. this.password = password;
  42. }
  43. }

 

配置bean

  1. <?xml version=”1.0″encoding=”UTF-8″?>
  2. <beansxmlns=”http://www.springframework.org/schema/beans”
  3. xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
  4. xmlns:p=”http://www.springframework.org/schema/p”
  5. xmlns:c=”http://www.springframework.org/schema/c”
  6. xsi:schemaLocation=”http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd”>
  8. <bean id=”user” class=”com.msb.bean.User” init-method=”initUser” destroy-method=”destoryUser”>
  9. <property name=”username” value=”xiaoming”></property>
  10. </bean>
  11. </beans>

测试bean

  1. packagemsb.test;
  2. importmsb.bean.User;
  3. importjunit.Test;
  4. importspringframework.context.ApplicationContext;
  5. importspringframework.context.support.ClassPathXmlApplicationContext;
  6. /**
  7. * @Author: Ma HaiYang
  8. * @Description: MircoMessage:Mark_7001
  9. */
  10. publicclass Test1 {
  11. @Test
  12. public void testGetBean(){
  13. ClassPathXmlApplicationContext context =new ClassPathXmlApplicationContext(“applicationContext.xml”);
  14. User user = context.getBean(“user”,User.class);
  15. out.println(“第四步:User对象从容器中获取”);
  16. // 关闭容器
  17. close();
  18. }
  19. }

 

关于后置处理器

1 通过构造器创建bean实例           执行构造器

2 为bean属性赋值                         执行set方法

3 把bean实例传递给bean的后置处理器的方法

4 初始化bean                                调用bean的初始化方法,需要配置指定调用的方法

5 把bean实例传递给bean的后置处理器的方法

6 bean的获取                                容器对象 getBean方法

7 容器关闭销毁bean                      调用销毁方法,需要配置指定调用的方法

 

 

1 创建后置处理器 实现 BeanPostProcesser  重写两个方法

  1. packagemsb.beanProcesser;
  2. importspringframework.beans.BeansException;
  3. importspringframework.beans.factory.config.BeanPostProcessor;
  4. /**
  5. * @Author: Ma HaiYang
  6. * @Description: MircoMessage:Mark_7001
  7. */
  8. publicclass MyBeanProcesser implements BeanPostProcessor {
  9. @Override
  10. public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  11. //Object bean      实例化的bean
  12. //String beanName  bean的id
  13. out.println(“bean:初始化方法之前”);
  14. return bean;// 这里必须return bean
  15. }
  16. @Override
  17. public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  18. out.println(“bean:初始化方法之后”);
  19. return bean;// 这里必须returnbean
  20. }
  21. }

2 配置后置处理器,对容器中的所有bean添加后置处理器的生命周期

  1. <?xml version=”1.0″encoding=”UTF-8″?>
  2. <beansxmlns=”http://www.springframework.org/schema/beans”
  3. xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
  4. xmlns:p=”http://www.springframework.org/schema/p”
  5. xmlns:c=”http://www.springframework.org/schema/c”
  6. xsi:schemaLocation=”http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd”>
  8. <bean id=”user” class=”com.msb.bean.User” init-method=”initUser” destroy-method=”destoryUser”>
  9. <property name=”username” value=”xiaoming”></property>
  10. </bean>
  11. <bean id=”myBeanProcesser” class=”com.msb.beanProcesser.MyBeanProcesser”></bean>
  12. </beans>

BeanPostProcessor接口作用:

如果我们想在Spring容器中完成bean实例化、配置以及其他初始化方法前后要添加一些自己逻辑处理。我们需要定义一个或多个BeanPostProcessor接口实现类,然后注册到Spring IoC容器中。

1、接口中的两个方法都要将传入的bean返回,而不能返回null,如果返回的是null那么我们通过getBean方法将得不到目标。

2、ApplicationContext会自动检测在配置文件中实现了BeanPostProcessor接口的所有bean,并把它们注册为后置处理器,然后在容器创建bean的适当时候调用它,因此部署一个后置处理器同部署其他的bean并没有什么区别。而使用BeanFactory实现的时候,bean 后置处理器必须通过代码显式地去注册,在IoC容器继承体系中的ConfigurableBeanFactory接口中定义了注册方法

6_Spring_Bean的自动装配

bean自动装配

 

通过property标签可以手动指定给属性进行注入

我们也可以通过自动转配,完成属性的自动注入,就是自动装配,可以简化DI的配置

 

准备实体类

  1. package com.msb.bean;
  2. /**
  3. * @Author: Ma HaiYang
  4. * @Description: MircoMessage:Mark_7001
  5. */
  6. publicclass Dept {
  7. }

 

  1. packagemsb.bean;
  2. /**
  3. * @Author: Ma HaiYang
  4. * @Description: MircoMessage:Mark_7001
  5. */
  6. publicclass Emp {
  7. private Dept dept;
  8. @Override
  9. public String toString() {
  10. return “Emp{” +
  11. “dept=” + dept +
  12. ‘}’;
  13. }
  14. public Dept getDept() {
  15. return dept;
  16. }
  17. public void setDept(Dept dept) {
  18. this.dept = dept;
  19. }
  20. public Emp() {
  21. }
  22. public Emp(Dept dept) {
  23. this.dept = dept;
  24. }
  25. }

 

配置文件

  1. <?xml version=”1.0″encoding=”UTF-8″?>
  2. <beansxmlns=”http://www.springframework.org/schema/beans”
  3. xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
  4. xmlns:p=”http://www.springframework.org/schema/p”
  5. xmlns:c=”http://www.springframework.org/schema/c”
  6. xsi:schemaLocation=”http://www.springframework.org/schema/beans
  7. http://www.springframework.org/schema/beans/spring-beans.xsd”>
  8. <bean id=”dept” class=”com.msb.bean.Dept”></bean>
  9. <!–
  10. autowire 属性控制自动将容器中的对象注入到当前对象的属性上
  11. byName 根据目标id值和属性值注入,要保证当前对象的属性值和目标对象的id值一致
  12. byType 根据类型注入,要保证相同类型的目标对象在容器中只有一个实例
  13. –>
  14. <bean id=”emp” class=”com.msb.bean.Emp” autowire=”byName”></bean>
  15. </beans>

 

测试代码

  1. packagemsb.test;
  2. importmsb.bean.Emp;
  3. importmsb.bean.User;
  4. importjunit.Test;
  5. importspringframework.context.support.ClassPathXmlApplicationContext;
  6. /**
  7. * @Author: Ma HaiYang
  8. * @Description: MircoMessage:Mark_7001
  9. */
  10. publicclass Test2 {
  11. @Test
  12. public void testGetBean(){
  13. ClassPathXmlApplicationContext context =new ClassPathXmlApplicationContext(“applicationContext2.xml”);
  14. Emp emp = context.getBean(“emp”, Emp.class);
  15. out.println(emp);
  16. }
  17. }

 

 

 

 

 

7_Spring_使用外部属性配置文件

spring容器可以读取.properties属性配置文件,可以将文件中的信息注入给bean

 

例如,引入Druid数据源,配置连接池信息

1  导入Druid依赖和mysql-connector依赖

  1. <dependency>
  2. <groupId>alibaba</groupId>
  3. <artifactId>druid</artifactId>
  4. <version>1.10</version>
  5. </dependency>
  6. <dependency>
  7. <groupId>mysql</groupId>
  8. <artifactId>mysql-connector-java</artifactId>
  9. <version>0.22</version>
  10. </dependency>

2 准备属性配置文件

resources目录下准备一个jdbc.properties属性配置文件

 

 

配置文件内容

  1. jdbc_driver=com.mysql.cj.jdbc.Driver
  2. jdbc_url=jdbc:mysql://0.0.1:3306/mydb?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
  3. jdbc_username=root
  4. jdbc_password=root

 

applicationContext中添加context名称空间 并读取属性配置文件

配置druid数据源将属性配置文件中的信息注入到连接池中

  1. <?xml version=”1.0″encoding=”UTF-8″?>
  2. <beansxmlns=”http://www.springframework.org/schema/beans”
  3. xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
  4. xmlns:p=”http://www.springframework.org/schema/p”
  5. xmlns:c=”http://www.springframework.org/schema/c”
  6.  xmlns:context=”http://www.springframework.org/schema/context”
  7. xsi:schemaLocation=”http://www.springframework.org/schema/beans
  8. http://www.springframework.org/schema/beans/spring-beans.xsd
  9. http://www.springframework.org/schema/context
  10. http://www.springframework.org/schema/context/spring-context.xsd
  11. “>
  12.  <context:property-placeholder location=”classpath:jdbc.properties”/>
  13. <bean id=”dataSource” class=”com.alibaba.druid.pool.DruidDataSource”>
  14. <property name=”username” value=”${jdbc_username}”></property>
  15. <property name=”password” value=”${jdbc_password}”></property>
  16. <property name=”url” value=”${jdbc_url}”></property>
  17. <property name=”driverClassName” value=”${jdbc_driver}”></property>
  18. </bean>
  19. </beans>

 

3 DEBUG测试代码

 

 

 

 

8_Spring_注解方式管理bean

1注解方式创建对象IOC

 

导入依赖 aop

 

@Component    放在类上,用于标记,告诉spring当前类需要由容器实例化bean并放入容器中

该注解有三个子注解

@Controller   用于实例化controller层bean

@Service        用于实例化service层bean

@Repository  用于实例化持久层bean

当不确定是哪一层,就用Component

这几个注解互相混用其实也可以,但是不推荐

 

第一步:在applicationContext.xml中配置开启注解扫描

  1. <?xml version=”1.0″encoding=”UTF-8″?>
  2. <beansxmlns=”http://www.springframework.org/schema/beans”
  3. xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
  4. xmlns:p=”http://www.springframework.org/schema/p”
  5. xmlns:c=”http://www.springframework.org/schema/c”
  6. xmlns:context=”http://www.springframework.org/schema/context”
  7. xsi:schemaLocation=”http://www.springframework.org/schema/beans
  8. http://www.springframework.org/schema/beans/spring-beans.xsd
  9. http://www.springframework.org/schema/context
  10. http://www.springframework.org/schema/context/spring-context.xsd
  11. “>
  12. <!–添加注解扫描,扫描指定的包,将包中的所有有注解的类实例化
  13. base-package 后面放要扫描的包
  14. 如果有多个包需要扫描,可以使用逗号隔开  com.msb.bean,com.msb.service
  15. 或者可以写上一层包路径  msb
  16. 可以通过注解指定bean的id@Component(“user1”)
  17. 如果不指定,则id默认是 类名首字母小写
  18. –>
  19. <context:component-scan base-package=”com.msb.bean”></context:component-scan>
  20. </beans>

第二步:在类上添加注解,让spring容器给我们创建bean实例并存储于容器中

  1. packagecom.msb.bean;
  2. importorg.springframework.stereotype.Component;
  3. /**
  4. * @Author: Ma HaiYang
  5. * @Description: MircoMessage:Mark_7001
  6. */
  7. @Component(value= “user1”)
  8. public class User {
  9. }

测试代码

  1. packagemsb.test;
  2. importmsb.bean.User;
  3. importjunit.Test;
  4. importspringframework.context.ApplicationContext;
  5. importspringframework.context.support.ClassPathXmlApplicationContext;
  6. /**
  7. * @Author: Ma HaiYang
  8. * @Description: MircoMessage:Mark_7001
  9. */
  10. publicclass Test1 {
  11. @Test
  12. public void testGetBean(){
  13. ApplicationContext context =new ClassPathXmlApplicationContext(“applicationContext.xml”);
  14. User user = context.getBean(“user1”, User.class);
  15. out.println(user);
  16. }
  17. }

组件扫描配置注解识别

  1. <!–
  2. use-default-filters=”false”
  3. 默认值为true 代表使用默认的扫描过滤器
  4. 默认的扫描过滤器会识别并包含 @Component @Controller @Service @Repository 四个注解
  5. 不使用默认的filter,使用我们自己的filter
  6. –>
  7. <!–控制只扫描Controller注解–>
  8. <context:component-scan base-package=”com.msb” use-default-filters=”false”>
  9. <context:include-filter type=”annotation” expression=”org.springframework.stereotype.Controller”/>
  10. </context:component-scan>
  11. <!–控制不扫描Controller注解–>
  12. <context:component-scan base-package=”com.msb” use-default-filters=”true”>
  13. <context:exclude-filter  type=”annotation” expression=”org.springframework.stereotype.Controller”/>
  14. </context:component-scan>

 

2注解方式依赖注入DI

 

@Autowired   根据属性数据类型自动装配

@Qualifier      根据属性名称注入依赖

@Resources   可以根据类型,也可以根据名称注入

@Value           注入普通数据类型(8+String)

项目结构如下

 

 

applicationContext.xml中配置包扫描和读取属性配置文件

 

Dao层

接口

 

实现类

 

 

 

让容器扫描 Service层,实例化对象

接口

 

实现类

  1. packagemsb.service.impl;
  2. importmsb.dao.UserDao;
  3. importmsb.service.UserService;
  4. importspringframework.beans.factory.annotation.Autowired;
  5. importspringframework.beans.factory.annotation.Qualifier;
  6. importspringframework.beans.factory.annotation.Value;
  7. importspringframework.stereotype.Service;
  8. importannotation.Resource;
  9. /**
  10. * @Author: Ma HaiYang
  11. * @Description: MircoMessage:Mark_7001
  12. */
  13. @Service
  14. publicclass UserServiceImpl implements UserService {
  15. /*
  16. *@Autowired
  17. * 根据类型到容器中去寻找对应的对象,找到后给当前属性赋值
  18. * 不需要依赖 set方法
  19. * 属性类型可以是接口,会自动匹配对应的实现类对象
  20. * @Autowired配合 @Qualifier,可以通过名称指定注入的对象
  21. *
  22. * @Resource 如果不配置name 那么就是根据类型注入
  23. * @Resource(name=”userDaoImplB”) 配置name,就是根据名称注入
  24. *
  25. *
  26. * @Resource  是JDK中javax包的注解
  27. * @Autowired 和 @Qualifier 是spring中的注解
  28. *
  29. * @Value 可以个普通属性赋值
  30. * @Value 可以使用${}这种表达式获取系统的变量值
  31. *        或者是.properties属性配置文件中的值
  32. *
  33. * */
  34. //@Autowired
  35. //@Qualifier(“userDaoImplA”)
  36. //@Qualifier(“userDaoImplB”)
  37. //private UserDao userDao ;
  38. @Resource(name=”userDaoImplB”)
  39. private UserDao userDao ;
  40. @Value(“${username}”)
  41. private String sname;
  42. @Value(“boy”)
  43. private String sgender;
  44. @Value(“${age}”)
  45. private Integer sage;
  46. @Override
  47. public void add() {
  48. out.println(“userServiceImpl add … … “);
  49. out.println(sname);
  50. out.println(sgender);
  51. out.println(sage);
  52. add();
  53. }
  54. }

测试代码

  1. packagemsb.test;
  2. importmsb.service.UserService;
  3. importjunit.Test;
  4. importspringframework.context.ApplicationContext;
  5. importspringframework.context.support.ClassPathXmlApplicationContext;
  6. /**
  7. * @Author: Ma HaiYang
  8. * @Description: MircoMessage:Mark_7001
  9. */
  10. publicclass Test1 {
  11. @Test
  12. public void testGetBean(){
  13. ApplicationContext context =new ClassPathXmlApplicationContext(“applicationContext.xml”);
  14. UserService userService = context.getBean(“userServiceImpl”, UserService.class);
  15. add();
  16. }
  17. }

3完全使用注解(了解)

创建配置类,替代XML配置文件

 

测试代码

  1. @Test
  2. public void testGetBean2(){
  3. ApplicationContext context=new AnnotationConfigApplicationContext(SpringConfig.class);
  4. UserServiceImpl userService = context.getBean(“userServiceImpl”, UserServiceImpl.class);
  5. add();
  6. }

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部