Spring介绍、Spring快速入门、加载Spring容器的三种方式、装配Bean的三种方式、Bean的作用域、Bean的生命周期-day01

第一节 Spring介绍

1.1 Spring概述

  • Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。Spring使用基本的JavaBean来完成以前只可能由EJB完成的事情。然而,Spring的用途不仅限于服务器端的开发。从简单性、可测试性和松耦合的角度而言,任何Java应用都可以从Spring中受益。简单来说,Spring是一个轻量级的控制反转(IOC)和面向切面(AOP)的容器框架。

1.2 Spring好处

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

1.3 Spring体系结构

  • Spring 框架是一个分层架构,它包含一系列的功能要素并被分为大约20个模块。这些模块分为Core Container、Data Access/Integration、Web、AOP(Aspect Oriented Programming)、Instrumentation和测试部分,如下图所示:
    在这里插入图片描述

1.4 Spring在项目中的架构

  • Web层:Struts,SpringMVC
  • Service层:Spring
  • Dao层:Hibernate,Mybatis
    在这里插入图片描述

第二节 Spring快速入门

2.1 下载Spring的开发包

2.2 Spring的核心jar包

  • spring-core-3.2.2.RELEASE.jar
    包含Spring框架基本的核心工具类,Spring其它组件要都要使用到这个包里的类,是其它组件的基本核心。
  • spring-beans-3.2.2.RELEASE.jar
    所有应用都要用到的,它包含访问配置文件、创建和管理bean以及进行Inversion of Control(IOC) / Dependency Injection(DI)操作相关的所有类。
  • spring-context-3.2.2.RELEASE.jar
    Spring提供在基础IOC功能上的扩展服务,此外还提供许多企业级服务的支持,如邮件服务、任务调度、JNDI定位、EJB集成、远程访问、缓存以及各种视图层框架的封装等。
  • spring-expression-3.2.2.RELEASE.jar
    Spring表达式语言
  • com.springsource.org.apache.commons.logging-1.1.1.jar
    第三方的jar包,主要用于处理日志。

2.3 Spring的入门案例

第一步:创建项目,导入相关jar包

  • spring-framework-3.2.0.RELEASE-dist.zip 【Spring的核心包】
  • spring-framework-3.0.2.RELEASE-dependencies.zip 【Spring的依赖包】
    在这里插入图片描述
  • 在依赖包中找到处理日志的jar包:com.springsource.org.apache.commons.logging-1.1.1.jar
  • 在核心包中找到其它jar包,并创建一个文件夹,存入

导入4核心(beans、core、context、expression) + 1个依赖(common-logging.jar)
注意导入时,不要导入带sources的源文件了

在这里插入图片描述

  • 创建一个spring项目
  • 这里不选择下载
    在这里插入图片描述
  • 选择自己配置的jar
    在这里插入图片描述

第二步:写一个简单的Service,并使用

  • UserService接口
package com.it.service;

public interface UserService {
    
    
    public void add();
}
  • UserServiceImpl并实现UserService接口
package com.it.service;

public class UserServiceImpl implements UserService{
    
    
    @Override
    public void add() {
    
    
        System.out.println("添加用户...");
    }
}
  • 简单测试一下,感受一下之前是怎么使用Service的
package com.it.test;

import com.it.service.UserServiceImpl;
import com.it.service.UserService;
import org.junit.Test;

public class demo01 {
    
    
    @Test
    public void test1(){
    
    
    	//以前使用Service,自己创建对象
        UserService userService = new UserServiceImpl();
        userService.add();
    }
}

在这里插入图片描述

第三步:Spring IOC控制反转创建实例

  1. 在src下写个配置文件beans.xml,配置文件的约束可以在spring-framework-3.2.0.RC2-docs/reference/html/xsd-config.html中查看
    在这里插入图片描述
    在这里插入图片描述
  • 有dtd约束也有xsd约束
    在这里插入图片描述
  • 将下面的约束复制粘贴进beans.xml中
    在这里插入图片描述
  • xsd初始配置
<?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 definitions here -->

</beans>
  1. 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">

    <!--配置一个bean【对象】-->
    <!--写接口的实现类,不能写接口-->
    <bean class="com.it.service.UserServiceImpl" id="userService"></bean>

</beans>

第四步:从beans.xml中获取bean

	//IOC控制反转实例
	@Test
    public void test2(){
    
    
        //以前使用Service,自己创建对象

        /*UserService userService = new UserServiceImpl();
        userService.add();*/

        //现在使用Service,从spring容器中取
        //1.加载spring配置文件 beans.xml ,spring容器内部就会创建对象
        //ClassPathXml表示从src下取
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");

        //2.从spring容器获取 userService对象(getBean根据id获取bean)
        UserService userService1 = (UserService) context.getBean("userService");
        userService1.add();

        UserService userService2 = (UserService) context.getBean("userService");
        userService2.add();

        //验证userService1和2是否是同一个
        System.out.println(userService1);
        System.out.println(userService2);

    }

在这里插入图片描述

IOC总结

  • IOC(Inverse of Control )反转控制,就是将原本在程序中手动创建UserService对象的控制权,交由Spring框架管理。简单的说,就是创建UserService对象控制权被反转到了Spring框架。

2.4 DI(依赖注入)

  • (DI)Dependency Injection 依赖注入,在Spring框架创建Bean对象时,动态的将依赖对象注入到Bean组件中。

依赖注入案例

  1. 在UserServiceImpl中提供一个get/set的name方法
    在这里插入图片描述
  • 此时如果不在beans.xml注入一个name值,执行test2,默认调用name的空参构造
    在这里插入图片描述
  1. 在beans.xml中通过property去注入一个name值
    在这里插入图片描述
  • 再次运行test2
    在这里插入图片描述
  • 如果不提供set方法会报错
    在这里插入图片描述
  • 依赖注入是调用属性的set方法给属性赋值
    在这里插入图片描述

第三节 加载Spring容器的三种方式

第一种方式:类路径获得配置文件【最常用】

  • 以后就把spring配置文件beans.xml放在src目录下即可
	@Test
    public void test1(){
    
    
        //spring容器加载的三种方式
        //第一种:类路径获取配置文件 ClassPathXmlApplicationContext
        //如果在包路径下,要写包名 例如:beans.xml在com.it.service包下要写成:com/it/service/beans.xml
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserService userService = (UserService) context.getBean("userService");
        userService.add();
    }

在这里插入图片描述

第二种方式:文件系统路径获得配置文件

	@Test
    public void test2(){
    
    
        //spring容器加载的三种方式
        //第二种:文件系统路径获得配置文件 FileSystemXmlApplicationContext
        //拷贝beans.xml的绝对路径,粘贴进去
        ApplicationContext context = new FileSystemXmlApplicationContext("D:\\Spring\\src\\beans.xml");
        UserService userService = (UserService) context.getBean("userService");
        userService.add();
    }

在这里插入图片描述

第三种方式:使用BeanFactory【了解】

	@Test
    public void test3(){
    
    
        //spring容器加载的三种方式
        //第三种:使用BeanFactory 【这种方法已过时】
        String path = "D:\\Spring\\src\\beans.xml";
        BeanFactory factory = new XmlBeanFactory(new FileSystemResource(path));
        UserService userService = (UserService) factory.getBean("userService");
        userService.add();
    }

在这里插入图片描述

spring内部创建对象的原理:
1.解析xml文件,获取类名,id,属性
2.通过反射,用类型创建对象
3.给创建的对象赋值

BeanFactory和ApplicationContext对比

  • 在UserServiceImpl中添加一个空参构造打印一句话
    在这里插入图片描述

  • BeanFactory采取延迟加载(懒加载),第一次getBean时才会初始化Bean
    在这里插入图片描述
    在这里插入图片描述

  • ApplicationContext采取即时加载
    在这里插入图片描述

  • ApplicationContext是对BeanFactory扩展,提供了更多功能

    • 国际化处理
    • 事件传递
    • Bean自动装配
    • 各种不同应用层的Context实现

第四节 装配Bean(xml)的三种方式

  • 所谓装配bean就是在xml中写一个bean标签。

第一种方式:通过new 实现类

在这里插入图片描述
在这里插入图片描述

第二种方式:通过静态工厂方法

  • 之前使用静态工厂
    在这里插入图片描述
    在这里插入图片描述
  • 通过bean使用静态工厂
    在这里插入图片描述
  • 由于spring版本低的问题(这里使用的是spring3.2)报错
    在这里插入图片描述
  • 降低jdk版本为1.7,即可解决
    在这里插入图片描述
    在这里插入图片描述

调用2次UserServiceImpl的原因:在beans1.xml中配置了2个bean,ApplicationContext是即时加载,都会加载进容器。

第三种方式:通过实例工厂方法

  • 所谓的实例就是要调用对象,不是调用类方法了。
  • 先复制UserServiceFactory改名为UserServiceFactory1,并去掉里面的static
    在这里插入图片描述
    在这里插入图片描述
  • 通过bean使用实例工厂
    在这里插入图片描述

在这里插入图片描述

第五节 bean的作用域

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

singleton 单例【默认值】

在这里插入图片描述

  • 默认单列,且里面只有一个bean,每次获取都是同一个对象,地址值相同
    在这里插入图片描述

prototype 多例

在这里插入图片描述
在这里插入图片描述

第六节 bean的生命周期【了解】

生命周期图

在这里插入图片描述

生命周期图解释

  1. instantiate:bean对象实例化
  2. populate properties:封装属性
  3. 如果Bean实现BeanNameAware:执行 setBeanName
  4. 如果Bean实现BeanFactoryAware:执行setBeanFactory ,获取Spring容器
  5. 如果存在类实现 BeanPostProcessor(后处理Bean) ,执行postProcessBeforeInitialization
  6. 如果Bean实现InitializingBean:执行 afterPropertiesSet
  7. 调用<bean init-method=“init”> 指定初始化方法 init
  8. 如果存在类实现 BeanPostProcessor(处理Bean) ,执行postProcessAfterInitialization执行业务处理
  9. 如果Bean实现 DisposableBean 执行 destroy
  10. 调用<bean destroy-method=“customerDestroy”> 指定销毁方法 customerDestroy

bean的生命周期演示

  • User.java
package com.it.model;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;

/**
 * @ClassName User
 * @Author shuyy
 * @Date 2020/9/9 19:42
 **/
public class User implements BeanNameAware, BeanFactoryAware, InitializingBean, DisposableBean {
    
    
    private String username;
    private String password;

    public User() {
    
    
        System.out.println("1.构造方法实例化...");
    }

    public String getUsername() {
    
    
        return username;
    }

    public void setUsername(String username) {
    
    
        System.out.println("2.设置属性username:"+username);
        this.username = username;
    }

    public String getPassword() {
    
    
        return password;
    }

    public void setPassword(String password) {
    
    
        System.out.println("2.设置属性password:"+password);
        this.password = password;
    }

    @Override
    public String toString() {
    
    
        return "User{" +
                "username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }

    @Override
    public void setBeanName(String s) {
    
    
        System.out.println("3.设置bean的名字:"+s);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
    
    
        //把对象放进工厂(就是把对象放进一个容器中)
        System.out.println("4.bean工厂:"+beanFactory);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
    
    
        System.out.println("6.属性赋值完成...");
    }

    public void myInit(){
    
    
        System.out.println("7.自定义的初始化方法...");
    }

    @Override
    public void destroy() throws Exception {
    
    
        //资源释放
        System.out.println("9.bean被销毁了...");
    }

    public void myDestroy(){
    
    
        //资源释放
        System.out.println("10.自定义的销毁方法...");
    }
}

  • MyBeanPostProcessor.java
package com.it.model;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

/**
 * @ClassName MyBeanPostProcessor
 * @Author shuyy
 * @Date 2020/9/9 
 **/
 //bean处理器,需要注册给Spring容器,统一处理所有的bean,只需要注册
public class MyBeanPostProcessor implements BeanPostProcessor {
    
    
    @Override
    public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
    
    
    	//后处理:在初始化前
        //这里可以用于多个对象共同处理的事
        System.out.println("5.预处理:"+o+":"+s);
        return o;
    }

    @Override
    public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
    
    
    	//后处理:在初始化后
        System.out.println("8.后处理:"+o+":"+s);
        return o;
    }
}

  • beans3.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">

    <!--bean的生命周期--><!--7.设置自定义初始化方法 myInit--><!--10.设置自定义销毁方法 myDestroy-->
    <bean class="com.it.model.User" id="user" init-method="myInit" destroy-method="myDestroy">
        <!--2.设置属性-->
        <property name="username" value="shu"></property>
        <property name="password" value="123"></property>
    </bean>

    <!--5、8配置bean处理器(无需配置id)-->
    <bean class="com.it.model.MyBeanPostProcessor"></bean>

</beans>
  • demo5.java
package com.it.test;

import com.it.model.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/*
 * @Author ShuYY
 * @Description bean的生命周期
 * @Date 19:34 2020/9/9
 * @Param 
 * @return 
 **/
public class demo05 {
    
    
    @Test
    public void test1() throws Exception {
    
    
        //bean的生命周期
        ApplicationContext context = new ClassPathXmlApplicationContext("beans3.xml");
        User user = (User) context.getBean("user");
        System.out.println(user);

        //手动关闭容器后,9.destroy销毁方法才会执行
        context.getClass().getMethod("close").invoke(context);
    }
}

  • 效果:
    在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_43414199/article/details/108466334