2021/08/16笔记

我们于2021/08/16 的学习目标是:Spring框架,核心任务为:

1、学习技术:

1)、Spring的概念

2)、Spring的环境搭建

3)、Spring IOC 容器 Bean 对象实例化模拟

4)、Spring IOC 配置文件加载

5)、Spring IOC 注入

6)、Spring IOC 扫描器

7)、Bean的作用域

8)、Bean的生命周期

2、文档总结

1)、Spring的概念

Spring是众多开源Java项目中的一员,基于分层的JavaEE应用一站式轻量级开源框架,主要核心是IOC(控制反转或依赖注入)和AOP(面向切面)两大技术,实现项目在开发过程中的轻松解耦,提高项目的开发效率。

在项目中引入Spring有以下好处:

  • 降低组件之间的耦合度,实现软件各层之间的解耦。
  • 可以使用容器提供的众多服务,如:事务管理服务、消息服务等等。
  • 当我们使用容器管理事务时,开发人员就不再需要手工控制事务,也不需处理复杂的事务传播。
  • 容器提供单例模式支持,开发人员不再需要自己编写实现代码。
  • 容器提供了AOP技术,利用它很容易实现如权限拦截、运行期监控等功能。

Spring源码架构:

  • 核心容器
  • Spring-AOP
  • Spring Data Access
  • Web模块
  • 报文发送
  • 单元测试

2)、Spring的环境搭建

环境要求:

  • JDK1.7及以上版本
  • Spring 5.x版本

步骤:

新建Maven的普通Java项目

org.apache.maven.archetypes:maven-archetype-quickstart

设置项目的位置、名称和附加信息

设置项目的Maven环境

设置项目的Maven环境

调整项目环境:

修改JDK版本

<properties>

   <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

   <!-- 修改JDK版本 -->

   <maven.compiler.source>11</maven.compiler.source>

   <maven.compiler.target>11</maven.compiler.target>

</properties>

修改单元测试的JUnit版本

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.12</version> <!-- 修改JUnit版本 -->

<scope>test</scope>

</dependency>

删除build标签中的pluginManagement标签

<build>

</build>

<!-- 删除此标签 -->

添加 Spring 框架的依赖坐标

<!-- 添加至dependencies标签内 -->

<dependency>

   <groupId>org.springframework</groupId>

   <artifactId>spring-context</artifactId>

   <version>5.2.14.RELEASE</version>

</dependency>

编写Bean对象

package com.sdf.service;



public class UserService {

   public void test(){

      System.out.println("UserService.test()");

   }

}

新建资源目录,在此目录下配置spring.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

      https://www.springframework.org/schema/beans/spring-beans.xsd">

   <!--

      xmlns 即 xml namespace xml使用的命名空间

      xmlns:xsi 即xml schema instance xml 遵守的具体规范

      xsi:schemaLocation 本文档xml遵守的规范 官方指定

   -->

   <bean id="userService" class="com.sdf.service.UserService"></bean>

</beans>

在spring.xml中配置Bean对象

<!--

   id:bean对象的id,唯一标识。一般是Bean对象的名称的首字母小写

   class:bean对象的类路径

-->

<bean id="userService" class="com.xxxx.service.UserService"></bean>

加载配置文件,获取实例化对象

package com.sdf;

import com.sdf.service.UserService;

import  org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;



public class AppTest{

   public static void main(String[] args){

      //获取Spring上下文环境

      ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml")

      //通过getBean方法得到Spring容器中实例化好的Bean对象

         //(实例化Bean对象)

      //userService代表的是配置文件中bean标签的id属性值

      UserService userService = (UserService) ac.getBean("userService");

      //调用方法

      userService.test();

   }



}

3)、Spring IOC 容器 Bean 对象实例化模拟

思路:

  1. 定义Bean工厂接口,提供获取Bean方法
  2. 定义Bean工厂接口实现类,解析配置文件,实例化Bean对象
  3. 实现获取Bean方法

定义Bean属性对象

package com.sdf.javabean;



import java.util.Objects;



public class MyBean {

    private String id;

    private String clazz;



    public MyBean() {

        System.out.println("MyBean.MyBean()");

    }



    public MyBean(String id, String clazz) {

        System.out.println("MyBean.MyBean(String id, String clazz)");

        this.id = id;

        this.clazz = clazz;

    }



    public String getId() {

        System.out.println("MyBean.getId");

        return id;

    }



    public MyBean setId(String id) {

        System.out.println("MyBean.setId");

        this.id = id;

        return this;

    }



    public String getClazz() {

        System.out.println("MyBean.getClazz");

        return clazz;

    }



    public MyBean setClazz(String clazz) {

        System.out.println("MyBean.setClazz");

        this.clazz = clazz;

        return this;

    }



    @Override

    public boolean equals(Object o) {

        System.out.println("MyBean.equals");

        if (this == o) return true;

        if (o == null || getClass() != o.getClass()) return false;

        MyBean myBean = (MyBean) o;

        return Objects.equals(id, myBean.id) &&

                Objects.equals(clazz, myBean.clazz);

    }



    @Override

    public int hashCode() {

        System.out.println("MyBean.hashCode");

        return Objects.hash(id, clazz);

    }



    @Override

    public String toString() {

        System.out.println("MyBean.toString");

        return "MyBean{" +

                "id='" + id + '\'' +

                ", clazz='" + clazz + '\'' +

                '}';

    }

}

添加dom4j坐标依赖

    <!-- dom4j -->

    <dependency>

      <groupId>dom4j</groupId>

      <artifactId>dom4j</artifactId>

      <version>1.6.1</version>

    </dependency>

    <!-- XPath -->

    <dependency>

      <groupId>jaxen</groupId>

      <artifactId>jaxen</artifactId>

      <version>1.1.6</version>

</dependency>

准备自定义配置文件

spring.xml

<?xml version="1.0" encoding="UTF-8" ?>

<beans>

    <bean id="userService" class="com.sdf.service.UserService"></bean>

</beans>

定义Bean工厂接口

package com.sdf.factory;



public interface MyFactory {

    public Object getBean(String id);

    //通过id值来获取对象

}

定义Bean接口的实现类

package com.sdf;



import com.sdf.javabean.MyBean;

import org.dom4j.io.SAXReader;

import org.springframework.beans.BeansException;

import org.springframework.beans.factory.BeanFactory;

import org.springframework.beans.factory.NoSuchBeanDefinitionException;

import org.springframework.beans.factory.ObjectProvider;

import org.springframework.core.ResolvableType;



import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import org.dom4j.*;

import java.net.URL;



public class MyClassPathXmlApplicationContext implements BeanFactory {

    //实例化后的对象放入Map

    private Map beans = new HashMap();

    //存放已读取bean配置信息

    private List<MyBean> myBeans;



    //空构造

    public MyClassPathXmlApplicationContext() {

    }



    //1.通过构造器得到相关配置信息

    public MyClassPathXmlApplicationContext(String fileName){

        //2.通过dom4j解析xml文件,得到List

            //存放id和class

        this.parseXml(fileName);

        //3.通过反射实例化得到对象Class.forname(类路径).newInstance();

            //通过Map存储

        this.instanceBean();



    }



    private void parseXml(String fileName) {

         // 1、获取解析器

        SAXReader reader = new SAXReader();

        // 2、得到配置文件的URL

        URL url = this.getClass().getClassLoader().getResource(fileName);

        try {

            // 3、通过解析器解析xml文件(spring.xml)

            Document document = reader.read(url);

            // 4、通过xpath语法,获取beans标签下的所有bean标签

            XPath xPath = document.createXPath("beans/bean");

            // 通过指定语法解析文档对象,返回集合

            List<Element> list = xPath.selectNodes(document);

            // 判断集合是否为空,遍历集合

            if (list != null && list.size() > 0) {

                myBeans = new ArrayList<>();

                for(Element el : list) {

                    // 获取标签元素中的属性

                    String id = el.attributeValue("id"); // id 属性值

                    String clazz = el.attributeValue("class"); // class 属性值

                    System.out.println(el.attributeValue("id"));

                    System.out.println(el.attributeValue("class"));

                    // 得到Bean对象

                    MyBean bean = new MyBean(id, clazz);

                    // 将Bean对象设置到集合中

                    myBeans.add(bean);

                }

            }

        } catch (DocumentException e) {

            e.printStackTrace();

        }

    }



    private void instanceBean() {

        // 判断bean集合是否为空,不为空遍历得到对应Bean对象

        if (myBeans != null && myBeans.size() > 0) {

            for (MyBean bean : myBeans) {

                try {

                    // 通过类的全路径实例化对象

                    Object object = Class.forName(bean.getClazz()).newInstance();

                    // 将id与实例化对象设置到map对象中

                    beans.put(bean.getId(), object);

                } catch (Exception e) {

                    e.printStackTrace();

                }

            }

        }

    }







    @Override

    public Object getBean(String s) throws BeansException {

        Object object = beans.get(s);

        return object;

    }



    @Override

    public <T> T getBean(String s, Class<T> aClass) throws BeansException {

        return null;

    }



    @Override

    public Object getBean(String s, Object... objects) throws BeansException {

        return null;

    }



    @Override

    public <T> T getBean(Class<T> aClass) throws BeansException {

        return null;

    }



    @Override

    public <T> T getBean(Class<T> aClass, Object... objects) throws BeansException {

        return null;

    }



    @Override

    public <T> ObjectProvider<T> getBeanProvider(Class<T> aClass) {

        return null;

    }



    @Override

    public <T> ObjectProvider<T> getBeanProvider(ResolvableType resolvableType) {

        return null;

    }



    @Override

    public boolean containsBean(String s) {

        return false;

    }



    @Override

    public boolean isSingleton(String s) throws NoSuchBeanDefinitionException {

        return false;

    }



    @Override

    public boolean isPrototype(String s) throws NoSuchBeanDefinitionException {

        return false;

    }



    @Override

    public boolean isTypeMatch(String s, ResolvableType resolvableType) throws NoSuchBeanDefinitionException {

        return false;

    }



    @Override

    public boolean isTypeMatch(String s, Class<?> aClass) throws NoSuchBeanDefinitionException {

        return false;

    }



    @Override

    public Class<?> getType(String s) throws NoSuchBeanDefinitionException {

        return null;

    }



    @Override

    public Class<?> getType(String s, boolean b) throws NoSuchBeanDefinitionException {

        return null;

    }



    @Override

    public String[] getAliases(String s) {

        return new String[0];

    }

}

测试自定义IOC容器

创建与配置文件中对应的Bean对象

准备UserService.java

public class UserService {

    public void test(){

        System.out.println("UserService.test");

    }

}

准备AccountService.java

package com.sdf.service;



public class AccountService {

    public void test(){

        System.out.println("AccountService.test");

    }

}

测试是否可以获取实例化的Bean对象

package com.sdf;

import com.yjxxt.spring.MyFactory;

import com.yjxxt.spring.MyClassPathXmlApplicationContext;

import com.yjxxt.service.AccountService;

import com.yjxxt.service.UserService;

public class App {

   public static void main(String[] args) {

      MyFactory factory = new

MyClassPathXmlApplicationContext("spring.xml");

      // 得到实例化对象

      UserService userService = (UserService) factory.getBean("userService");

      userService.test();

      UserService userService2 = (UserService) factory.getBean("userService");

      System.out.println(userService+"=====" + userService2);

      AccountService accountService  (AccountService)factory.getBean("accountService");

accountService.test();

   }

}

Spring容器在启动时读取xml信息,并对配置的Bean进行实例化(仅供理解),同时通过上下文对象提供的getBean()方法拿到我们配置的Bean对象,从而实现外部容器自动化维护并创建Bean效果。

4)、Spring IOC 配置文件加载

根据相对路径加载资源

Application ac = new ClassPathXmlApplicationContext("spring.xml");

根据绝对路径加载资源

Application ac = new FileSystemXmlApplicationContext("S:/d/f/3/4/5/1/9/9/9/IdeaWorkspace/spring01/src/main/resources/spring.xml");

Spring多配置文件加载

Spring框架启动时可以加载多个配置文件到环境中。

对于比较复杂的项目,可能对应的配置文件有多个,项目在启动部署时会将多个配置文件同时加载到进程中。

service.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

      https://www.springframework.org/schema/beans/spring-beans.xsd">

   <bean id="userService" class="com.xxxx.service.UserService"></bean>

</beans>

dao.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

   https://www.springframework.org/schema/beans/spring-beans.xsd">

   <bean id="userDao" class="com.xxxx.dao.UserDao"></bean>

</beans>

可变参数,可传入多个文件名

//可同时加载多个资源文件

ApplicationContext ac = new ClassPathXmlApplicationContext("spring.xml","dao.xml")

通过总的配置文件导入其他配置文件

spring.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

   https://www.springframework.org/schema/beans/spring-beans.xsd">

   <!--导入需要包含的资源文件-->

   <import resource="service.xml"/>

   <import resource="dao.xml"/>

</beans>

加载时只需要加载总配置文件即可

//加载总的资源文件

Application ac = new ClassPathXmlApplicationContext("spring.xml");

5)、Spring IOC 注入

  • set方法注入
  • 构造器注入
  • 静态工厂注入
  • 实例化工厂注入

开发项目中首选set方式注入。

@Autowired注解实现自动化注入:

默认通过类型(Class类型)查找Bean对象

   与属性字段的名称无关

属性可以提供set方法,也可不提供

注解可以声明在属性级别或set方法级别

可以添加@Qualifier结合使用,通过value属性值查找bean对象

   (value属性值必须要设置,且值要与bean标签的id属性值对

   应)

@Autowired 与 @Resource的区别

  1. @Autowired 来自 Spring框架,@Resource 来自 javax包
  2. @Autowired 根据类型装配,@Resource根据名称装配
  3. 一般@Autowired若遇到同一类型的数据不唯一,可以使用@Qualifier(value="")指定具体的对象名称
  4. @Resource根据名称装配,若根据名称有多个类型的对象,可指定具体的对象

6)、Spring IOC 扫描器

作用:bean对象通用进行管理,简化开发配置,提高开发效率

使用:

1.设置自动化扫描的范围

   如果bean对象未在指定包范围,即使声明的注解,也无法实例化

2.使用指定的注解(声明在类级别)

   bean对象的id属性默认是类名首字母为小写的类

   Dao层:@Reposition

   Service层:@Service

   Controller层:@Controller

   任意类:@Component

注意:

   开发时建议按照指定规则声明注解

7)、Bean的作用域

  • singleton作用域
  • prototype作用域

8)、Bean的生命周期

  1. 容器启动装载并实例化servlet类
  2. 初始化Servlet
  3. 调用Servlet方法
  4. 销毁Servlet
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值