Spring1(初始Spring 解耦实现 SpringIOC SpringDI Spring常见面试题)

news2024/11/5 20:57:15

Spring1

  • 创建项目
    • 集成maven
    • 创建一个Maven项目
    • 实现:
  • 初识Spring
    • Spring简介
    • Spring的发展历史
    • Spring之父
    • 体系结构
    • 生态系统
    • 官方文档
    • 解耦实现
      • JDBC
      • SpringBoot整合MyBatis和lombok,开启驼峰映射
      • 三层思想
  • SpringIOC
    • 实现
  • SpringDI
    • set注入
      • 全部代码:
      • 实现:set注入基本数据类型与String
      • 实现:set注入javabean对象
      • 实现:set注入复杂类型
    • 构造注入:
      • 全部代码:
      • 实现:构造注入基本类型与String类型
      • 实现:构造注入javabean对象
  • Spring常见面试题
    • Spring 框架的基本理解
    • Spring 框架由哪些模块组成?
    • Spring IOC的理解
    • Spring IOC容器的理解
    • Spring DI的理解

创建项目

集成maven

创建一个Maven项目

实现:

在pom配置依赖:

初识Spring

Spring简介

Spring是分层的轻量级开源框架,以IoC[反转控制]和AoP[面向切面编程]为内核,提供了展现层SpringMVC和持久层SpringJDBC以及业务层的事务管理。

Spring 是分层的 Java SE/EE 应⽤ full-stack 轻量级开源框架,以IoC(Inverse Of Control:反转控制)和AOP(Aspect Oriented Programming:面向切⾯编程)为内核,提供了展现层 Spring MVC 和持久层 Spring JDBC 以及业务层事务管理等众多的企业级应⽤技术,还能整合开源世界众多著名的第三⽅框架和类库,逐渐成为使⽤最多的 Java EE 企业应⽤开源框架。

官方网站:https://spring.io/

Spring的发展历史

企业级应用指的是 大规模、性能和安全要求高、业务复杂、灵活多变 的大型 WEB 应用程序。

  • 大规模:用户量和 IP/PV访问量大、海量数据、功能模块多代码量大。
  • 业务复杂:涉及金融、期货、电信等特殊领域的业务逻辑复杂,对系统架构提出新要求。
  • 性能和安全要求高:响应毫秒数和安全级别均有很高的要求。
  • 灵活多变:经常性的业务变更,也对开发效率以及项目部署等工作有更高的要求。

重量级技术向轻量级开发过度

为了实现企业级应用开发各类需求,涌现出以EJB为代表的一系列技术。

Spring之父

Rod Johnson,SpringFramework创始人, interface21 CEO。

• 1996 年开始关注 Java 服务器端技术

• Servlet2.4 和 JDO2.0 专家组成员

• Expert One-to-One J2EE Design and Development(2002)

• 阐述了 J2EE 使用EJB 开发设计的优点及解决方案

• Expert One-to-One J2EE Development without EJB(2004)

• 阐述了 J2EE 开发不使用 EJB的解决方式(Spring 雏形 )

• 2004年3月24日发布了Spring Framework 1.0 final

技术主张:技术应当回归实用为主,简化 Java 开发

Spring的理论基础:Spring 框架建立在本书中对于J2EE企业级应用的开发与设计的核心理念之上,追求简洁、轻量级的开发方式,让系统具备更好的健壮性和可扩展性。

体系结构

  • Spring Core:Spring框架的最基础部分,提供DI(依赖注入)特性。
  • Spring Context:Spring上下文,提供Bean容器的集合。
  • Spring AOP:基于Spring Core的符合规范的切面编程的实现。
  • Spring JDBC:提供了JDBC的抽象层,简化了JDBC编码。
  • Spring ORM:对主流ORM框架(Hibernate、Toplink等)进行集成。
  • Spring Web:为Spring在Web应用程序中的使用提供了支持。

生态系统

  • Spring Boot:简化产品级的 Spring 应用和服务的创建,简化了配置文件,使用嵌入式web服务器,含有诸多开箱即用微服务功能。
  • Spring Data:是一个数据访问及操作的工具包,封装了很多种数据及数据库的访问相关技术,包括:jdbc、Redis、MongoDB、Neo4j等。
  • Spring AMQP:消息队列操作的工具包,主要是封装了RabbitMQ的操作。
  • Spring Cloud:微服务工具包,用于创建基于云计算架构的原生微服务应用。
  • Spring Security:是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。
  • Spring Mobile:是Spring MVC的扩展,用来简化手机上的Web应用开发。

Spring【Spring FrameWork】解决的问题:

官方文档

Spring文档:https://docs.spring.io/spring-framework/docs/5.2.25.RELEASE/spring-framework-reference/core.html#spring-core

解耦实现

Spring的两大核心思想:IOC和AOP

  • SpringIOC(控制反转)SpringDI(依赖注入)
  • SpringAOP(面向切面思想)

SpringIOC:SpringIOC容器扮演项目的载体,IOC容器是可以使项目更符合高内聚,低耦合的思想“解耦”

耦合:类与类之间有耦合,方法与方法有耦合

解耦:

  • 尽量避免new对象,通过反射实例化
  • 需要创建的对象不要写死,而是把类名保存在独立的Properties文件中按需加载

JDBC

package com.stringzhua;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

/**
 * @Author Stringzhua
 * @Date 2024/9/9 19:30
 * description:
 */
class Test01 {
    public static void main(String[] args) {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection root = DriverManager.getConnection("jdbc:mysql://localhost:3306/lmonkeyshop?serverTimezone=GMT", "root", "12345678");
            System.out.println(root);
        } catch (ClassNotFoundException exception) {
            exception.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}

SpringBoot整合MyBatis和lombok,开启驼峰映射

=================mybaits自动驼峰映射====================
JavaBean                DB
stuId                   stu_id
stuName                 stu_name
<!--自动驼峰映射-->
<settings>
  <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>


=================junit====================
含义:方法级别的单元测试工具
步骤:
    1.坐标
    2.注解
        @Test=============main
        @Before===========main执行之前
        @After============main执行之后


=================lombok====================
步骤:
    1.idea安装插件(只安装一次)
    2.坐标
    3.注解

项目结构如下:
在这里插入图片描述

Dao层:

StudentMapper.java

package com.stringzhua.dao;

import com.stringzhua.pojo.Student;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;

import java.util.List;

/**
 * @Author Stringzhua
 * @Date 2024/9/9 16:08
 * description:mybatis 的 mapper
 */
public interface StudentMapper {

    @Select("select * from student")
    public List<Student> findAll();

    @Insert("insert into student(stu_name,nick_name,stu_age) values (#{stuName},#{nickName},#{stuAge})")
    public void add(Student s);
}

mybatis.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <!--自动驼峰映射-->
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <!--开发模式-->
    <environments default="env">
        <environment id="env">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mavendb?serverTimezone=Asia/Shanghai"/>
                <property name="username" value="root"/>
                <property name="password" value="12345678"/>
            </dataSource>
        </environment>
    </environments>

    <!--映射器注册-->
    <mappers>
        <package name="com.stringzhua.dao"/>
    </mappers>

</configuration>

POJO层:

Stundet.java

package com.stringzhua.pojo;

import lombok.*;

import java.io.Serializable;

/**
 * @Author Stringzhua
 * @Date 2024/9/9 16:03
 * description:
 */


/**
 * @AllArgsConstructor 满参构造
 * @NoArgsConstructor 无参构造
 * @ToString toString方法
 * @Getter getter方法
 * @Setter setter方法
 * @Data 提供类的get、set、equals、hashCode、canEqual、toString方法
 *
 * canEqual
 * 除非您的类 isfinal和 extends java.lang.Object,
 * 否则 lombok 会生成一个canEqual方法,这意味着 JPA 代理
 * 仍然可以等于它们的基类,但是添加新状态的子类不会破坏 equals 契约。
 */

@NoArgsConstructor
@Data
public class Student implements Serializable {
    private int stuId;
    private String stuName;
    private String nickName;
    private int stuAge;

    public Student(String stuName, String nickName, int stuAge) {
        this.stuName = stuName;
        this.nickName = nickName;
        this.stuAge = stuAge;
    }
}

单元测试:

package com.stringzhua.test;

import com.stringzhua.pojo.Student;
import com.stringzhua.dao.StudentMapper;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

/**
 * @Author Stringzhua
 * @Date 2024/9/9 16:14
 * description:
 * @Before 指的是@Test注解运行之前要执行的方法
 * @Test 指的是要执行测试的方法
 * @After 指的是@Test注解运行之后执行的方法
 */
public class Test01 {
    SqlSession sqlSession = null;
    StudentMapper studentmapper = null;

    @Before
    public void beforeMethod() {
        try {
            InputStream inputStream = Resources.getResourceAsStream("mybatis.xml");
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            SqlSessionFactory factory = sqlSessionFactoryBuilder.build(inputStream);
            sqlSession = factory.openSession(true);
            studentmapper = sqlSession.getMapper(StudentMapper.class);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @After
    public void afterMethod() {
        sqlSession.close();
    }


    @Test
    public void show1() throws Exception {


        studentmapper.add(new Student("猫猫", "千逐", 18));
        studentmapper.add(new Student("田欣怡", "晞苒", 22));
    }

    @Test
    public void show2() throws Exception {
        List<Student> all = studentmapper.findAll();
        for (int i = 0; i < all.size(); i++) {
            Student student = all.get(i);
            System.out.println(student);
        }
    }
}

三层思想

项目结构如下:

首先需要在main—>resources下新建一个properties配置文件

service=com.stringzhua.service.UserServiceImpl
dao=com.stringzhua.dao.UserDaoImpl

Controller层:

IUserController.java

package com.stringzhua.controller;

public interface IUserController {
    public void save();
}

UserControllerImpl.java

package com.stringzhua.controller;


import com.stringzhua.service.IUserService;
import com.stringzhua.util.BeansFactory;

public class UserControllerImpl implements IUserController {

    //耦合度高
//    IUserService service = new UserServiceImp();

    //耦合度低,通过工厂创建service对象
    IUserService service = (IUserService) BeansFactory.getBean("service");

    public void save() {
        System.out.println("===controller的新增===");
        service.save();
    }
}

Dao层:

IUserDao.java

package com.stringzhua.dao;

public interface IUserDao {
    public void save();
}

UserDaoImpl.java

package com.stringzhua.dao;

public class UserDaoImpl implements IUserDao{

    public void save() {
        System.out.println("===dao的新增===");
    }
}

Service层:

IUserService.java

package com.stringzhua.service;

public interface IUserService {
    public void save();
}

UserServiceImpl.java

package com.stringzhua.service;


import com.stringzhua.dao.IUserDao;
import com.stringzhua.util.BeansFactory;

public class UserServiceImpl implements IUserService{


    //耦合度高
//    IUserDao dao = new UserDaoImp();

    //耦合度低,通过工厂去创建dao对象
    IUserDao dao = (IUserDao) BeansFactory.getBean("dao");


    public void save() {
        System.out.println("===serivce的新增===");
        dao.save();
    }
}

Utils工具类:

BeansFactory.java

package com.stringzhua.util;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

public class BeansFactory {

    static Properties properties;

    static {
        try {
            //1.工具类
            properties = new Properties();
            //2.加载文件
            InputStream resourceAsStream = BeansFactory.class.getClassLoader().getResourceAsStream("beans.properties");
            properties.load(resourceAsStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static Object getBean(String key) {
        Object object = null;
        try {
            //1.获取key对应的value
            String classPath = properties.getProperty(key);
            //2.创建对象,反射,newInstance()去创建对象
            object = Class.forName(classPath).newInstance();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException exception) {
            exception.printStackTrace();
        }
        return object;
    }
}

测试:

package com.stringzhua.test;


import com.stringzhua.controller.IUserController;
import com.stringzhua.controller.UserControllerImpl;

public class Test01 {
    public static void main(String[] args) {
        IUserController controller = new UserControllerImpl();
        controller.save();
    }
}

SpringIOC

Spring环境搭建:

坐标---->配置文件

SpringIOC:控制反转

关键字:IOC名词解释,作用是解耦,使用IOC容器管理项目组件之间的耦合关系

IOC(Inversion Of Control 中文释义:控制反转)是Spring框架的核心思想之一,主要用于解耦。IOC是将创建的对象的控制权交给Spring框架进行管理。由Spring框架根据配置文件或注解等方式,创建Bean对象并管理各个Bean对象之间的依赖关系,使对象之间形成松散耦合的关系,实现解耦。

控制:指的是对象创建(实例化、管理)的权力

反转:控制权交给外部环境(Spring框架、IOC容器)

SpringIOC使用步骤:

  1. 创建类
  2. 将需要Spring管理的类,注入SpringIOC容器
<bean id="唯一标识" class="类的完全限定名称"></bean>
  1. 以解耦的方式获取JavaBean实例对象
    1. 加载Spring主配置文件,获取Spring核心对象
            ApplicationContext applicationContext =  new ClassPathXmlApplicationContext("beans.xml");
2. 获取JavaBean
Student  student = (Student) applicationContext.getBean("student");

实现

在pom.xml中配置:

<dependencies>
  <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.3.25</version>
  </dependency>
</dependencies>

项目结构如下图所示:

Controller层:

IUserController.java

package com.stringzhua.controller;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 14:28
 * description:
 */
public interface IUserController {
    public void add();
}

UserControllerImpl.java

package com.stringzhua.controller;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 14:29
 * description:
 */
public class UserControllerImpl implements  IUserController{
    public void add() {
        System.out.println("=====controller层的save()====");
    }
}

Dao层:

IUserDao.java

package com.stringzhua.dao;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 14:37
 * description:
 */
public interface IUserDao {
    public void add();
}

UserDaoImpl.java

package com.stringzhua.dao;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 14:37
 * description:
 */
public class UserDaoImpl implements IUserDao{
    public void add() {
        System.out.println("=====dao层的add()====");
    }
}

POJO层:

Student.java

package com.stringzhua.pojo;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 14:21
 * description:
 */
public class Student {

}

Service层:

IUserService.java

package com.stringzhua.service;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 14:38
 * description:
 */
public interface IUserService {
    public void add();
}	

UserServiceImpl.java

package com.stringzhua.service;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 14:38
 * description:
 */
public class UserServiceImpl implements IUserService{
    public void add() {
        System.out.println("=====service层的add()====");
    }
}

测试类:

package com.stringzhua.test;

import com.stringzhua.controller.IUserController;
import com.stringzhua.dao.IUserDao;
import com.stringzhua.pojo.Student;
import com.stringzhua.service.IUserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.Date;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 14:22
 * description:
 */
public class Test01 {
    public static void main(String[] args) {
        //1.加载spring主配置文件获取ioc容器对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
        //2.获取javaBean
        //默认为Object类型的对象,需要转换类型
        Student student = (Student) applicationContext.getBean("student");
        System.out.println(student);

        IUserController controller = (IUserController) applicationContext.getBean("controller");
        controller.add();
        IUserService service = (IUserService) applicationContext.getBean("service");
        service.add();
        IUserDao dao = (IUserDao) applicationContext.getBean("dao");
        dao.add();

        Date date = (Date) applicationContext.getBean("date");
        System.out.println(date);
    }
}

两个Demo的对比:

SpringDI

SpringDI:依赖注入

DI(Dependency Inject,中文释义:依赖注入)

是对IOC概念的不同角度的描述,是指应用程序在运行时,每一个Bean对象都要依赖IOC容器注入当前Bean对象所需要的另外一个Bean对象。

例如:在MyBatis整合Spring时,SqlSessionFactoryBean依赖IOC注入一个DataSource数据源Bean

SpringDI的实现方式:

  • set注入
  • 构造注入
  • 注解注入

SpringDI支持的数据类型:

  • 基本数据类型与String类型
  • JavaBean对象
  • 复杂类型(构造注入不支持)

DI实现步骤:

  1. 思考
  2. 提供对应方法(set) set(XXXXX)
  3. 配置
<property 属性名="属性值"></property>
        属性:
           name:属性名
           ref:注入的值的引用
           value:注入的值

DI实现步骤 (构造实现):

  1. 思考
  2. 提供对应的构造方法(构造)
  3. 配置
 <constructor-arg 属性名="属性值"></constructor-arg>
         属性:
           name:属性名
           type: 参数类型
           index: 参数下标
           ref:注入的值的引用
           value:注入的值

总结IOC和DI

原来要对象,自己造自己用

现在要对象,容器造,容器拼一块,自己用

“Spring胶水框架”

set注入

在pom.xml中进行配置:

 <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.25</version>
</dependency>

项目结构:

全部代码:

Controller层:

IUserController.java

package com.stringzhua.controller;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 16:02
 * description:
 */
public interface IUserController {
    public void add();
}

UserControllerImpl.java

package com.stringzhua.controller;

import com.stringzhua.service.IUserService;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 16:03
 * description:
 */
public class UserControllerImpl implements IUserController {

    IUserService service;
    //di注入步骤1:提供set方法
    public void setService(IUserService service) {
        this.service = service;
    }

    public void add() {
        System.out.println("==controller层的add方法==");
        service.add();
    }
}

Dao层:

IUserDao.java

package com.stringzhua.dao;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 15:59
 * description:
 */
public interface IUserDao {
    public void add();
}
package com.stringzhua.dao;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 16:00
 * description:
 */
public class UserDaoImpl implements IUserDao{
    public void add() {
        System.out.println("=====Dao层的add方法===");
    }
}

POJO层:

Student.java

package com.stringzhua.pojo;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 15:54
 * description:
 */
public class Student {
    private String stuName;
    private int stuAge;
    //di步骤1:提供set方法

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    public void setStuAge(int stuAge) {
        this.stuAge = stuAge;
    }

    @Override
    public String toString() {
        return "Student{" +
                "stuName='" + stuName + '\'' +
                ", stuAge=" + stuAge +
                '}';
    }
}

Teacher.java

package com.stringzhua.pojo;

import java.util.*;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 17:06
 * description:
 */
public class Teacher {
    private List mylist;
    private Set myset;
    private String[] myarray;
    private Map mymap;
    private Properties prop;

    public void setMylist(List mylist) {
        this.mylist = mylist;
    }

    public void setMyset(Set myset) {
        this.myset = myset;
    }

    public void setMyarray(String[] myarray) {
        this.myarray = myarray;
    }

    public void setMymap(Map mymap) {
        this.mymap = mymap;
    }

    public void setProp(Properties prop) {
        this.prop = prop;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "mylist=" + mylist +
                ", myset=" + myset +
                ", myarray=" + Arrays.toString(myarray) +
                ", mymap=" + mymap +
                ", prop=" + prop +
                '}';
    }
}

Service层:

IUserService.java

package com.stringzhua.service;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 16:01
 * description:
 */
public interface IUserService {
    public void add();
}

UserServiceImpl.java

package com.stringzhua.service;

import com.stringzhua.dao.IUserDao;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 16:01
 * description:
 */
public class UserServiceImpl implements IUserService {
    IUserDao dao;

    public void setDao(IUserDao dao) {
        this.dao = dao;
    }

    public void add() {
        System.out.println("==Service层的add方法==");
        dao.add();
    }
}

测试类:

Test.java

package com.stringzhua.test;

import com.stringzhua.controller.IUserController;
import com.stringzhua.pojo.Student;
import com.stringzhua.pojo.Teacher;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 15:57
 * description:
 */
public class Test01 {
    public static void main(String[] args) {
        //1.获取Application对象
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.获取JavaBean
        Student student = (Student) applicationContext.getBean("student");
        System.out.println(student);

        IUserController controller = (IUserController) applicationContext.getBean("controllerImpl");
        controller.add();

        Teacher teacher = (Teacher) applicationContext.getBean("teacher");
        System.out.println(teacher);
    }
}

实现:set注入基本数据类型与String

applicationContext.xml

 <!--    set注入基本数据类型与String-->
    <bean id="student" class="com.stringzhua.pojo.Student">
        <property name="stuName" value="晞冉"></property>
        <property name="stuAge" value="20"></property>
    </bean>
//1.获取Application对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.获取JavaBean
Student student = (Student) applicationContext.getBean("student");
System.out.println(student);

实现:set注入javabean对象

applicationContext.xml

 <!--    set注入JavaBean-->
<bean id="daoImpl" class="com.stringzhua.dao.UserDaoImpl"></bean>

<bean id="serviceImpl" class="com.stringzhua.service.UserServiceImpl">
    <property name="dao" ref="daoImpl"></property>
</bean>

<bean id="controllerImpl" class="com.stringzhua.controller.UserControllerImpl">
    <property name="service" ref="serviceImpl"></property>
</bean>
//1.获取Application对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.获取JavaBean
IUserController controller = (IUserController) applicationContext.getBean("controllerImpl");
controller.add();

实现:set注入复杂类型

applicationContext.xml

<!--    set注入复杂类型-->
<bean id="teacher" class="com.stringzhua.pojo.Teacher">
<property name="mylist">
    <list>
        <value>有何不可</value>
        <value>断桥残雪</value>
        <value>千百度</value>
        <value>老古董</value>
        <value>三尺</value>
    </list>
</property>

<property name="myset">
    <set>
        <value>田晞冉</value>
        <value>李芸芸</value>
        <value>董万鹏</value>
        <value>高夏斌</value>
    </set>
</property>

<property name="myarray">
    <array>
        <value>雁塔区</value>
        <value>莲湖区</value>
        <value>长安区</value>
        <value>长安区</value>
        <value>高新区</value>
    </array>
</property>

<property name="mymap">
    <map>
        <entry key="袁继峰" value="男"></entry>
        <entry key="陈博文" value="男"></entry>
        <entry key="郭忠航" value="男"></entry>
    </map>
</property>

<property name="prop">
    <props>
        <prop key="王文茜">已毕业</prop>
        <prop key="赵文瑜">未毕业,大四</prop>
        <prop key="张玉婷">文科专业转码</prop>
    </props>
</property>
//1.获取Application对象
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.获取JavaBean
Teacher teacher = (Teacher) applicationContext.getBean("teacher");
System.out.println(teacher);

构造注入:

pom.xml

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.25</version>
        </dependency>
    </dependencies>

项目结构:

全部代码:

Controller层:

IUserController.java

package com.stringzhua.controller;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 18:00
 * description:
 */
public interface IUserController {
    public void add();
}

UserControllerImpl.java

package com.stringzhua.controller;

import com.stringzhua.service.IUserSerivce;
import com.stringzhua.service.UserServiceImpl;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 18:01
 * description:
 */
public class UserControllerImpl implements IUserController {
    IUserSerivce serivce;

    public UserControllerImpl() {
    }

    public UserControllerImpl(IUserSerivce serivce) {
        this.serivce = serivce;
    }

    public void add() {
        System.out.println("==UserController层的add方法==");
        serivce.add();
    }
}

Dao层:

IUser.java

package com.stringzhua.dao;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 17:57
 * description:
 */
public interface IUserDao {
    public void add();
}

UserDaoImpl.java

package com.stringzhua.dao;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 17:58
 * description:
 */
public class UserDaoImpl implements IUserDao {

    public void add() {
        System.out.println("==UserDao层的add方法==");
    }
}

POJO层:

Student.java

package com.stringzhua.pojo;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 17:50
 * description:
 */
public class Student {
    private String stuName;
    private int stuAge;

    public Student() {
    }

    public Student(String stuName, int stuAge) {
        this.stuName = stuName;
        this.stuAge = stuAge;
    }

    @Override
    public String toString() {
        return "Student{" +
                "stuName='" + stuName + '\'' +
                ", stuAge=" + stuAge +
                '}';
    }
}

Service层;

IUserService.java

package com.stringzhua.service;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 17:59
 * description:
 */
public interface IUserSerivce {
    public void add();
}

UserServiceImpl.java

package com.stringzhua.service;

import com.stringzhua.dao.IUserDao;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 17:59
 * description:
 */
public class UserServiceImpl implements IUserSerivce {
    IUserDao dao;

    public UserServiceImpl() {
    }

    public UserServiceImpl(IUserDao dao) {
        this.dao = dao;
    }

    public void add() {
        System.out.println("==UserSerivce层的add方法==");
        dao.add();
    }
}

Test:

test.java

package com.stringzhua.service;

import com.stringzhua.dao.IUserDao;

/**
 * @Author Stringzhua
 * @Date 2024/9/10 17:59
 * description:
 */
public class UserServiceImpl implements IUserSerivce {
    IUserDao dao;

    public UserServiceImpl() {
    }

    public UserServiceImpl(IUserDao dao) {
        this.dao = dao;
    }

    public void add() {
        System.out.println("==UserSerivce层的add方法==");
        dao.add();
    }
}

applicationContext.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">
    <!--    构造注入基本类型与String-->
<!--    <bean id="student" class="com.stringzhua.pojo.Student">-->
<!--        <constructor-arg name="stuName" value="晞冉"></constructor-arg>-->
<!--        <constructor-arg name="stuAge" value="18"></constructor-arg>-->
<!--    </bean>-->
<!--    <bean id="student" class="com.stringzhua.pojo.Student">-->
<!--        <constructor-arg index="0" value="晞冉"></constructor-arg>-->
<!--        <constructor-arg index="1" value="18"></constructor-arg>-->
<!--    </bean>-->
    <bean id="student" class="com.stringzhua.pojo.Student">
        <constructor-arg type="java.lang.String" value="晞冉"></constructor-arg>
        <constructor-arg type="int" value="18"></constructor-arg>
    </bean>

    <!--    ==构造注入javabean==-->
    <bean id="daoImpl" class="com.stringzhua.dao.UserDaoImpl"></bean>

    <bean id="serviceImpl" class="com.stringzhua.service.UserServiceImpl">
        <constructor-arg name="dao" ref="daoImpl"></constructor-arg>
    </bean>

    <bean id="controllerImpl" class="com.stringzhua.controller.UserControllerImpl">
        <constructor-arg name="serivce" ref="serviceImpl"></constructor-arg>
    </bean>
</beans>

实现:构造注入基本类型与String类型

applicationContext.xml

<bean id="student" class="com.stringzhua.pojo.Student">
        <constructor-arg name="stuName" value="晞冉"></constructor-arg>
        <constructor-arg name="stuAge" value="18"></constructor-arg>
    </bean>
    <bean id="student" class="com.stringzhua.pojo.Student">
        <constructor-arg index="0" value="晞冉"></constructor-arg>
        <constructor-arg index="1" value="18"></constructor-arg>
    </bean>
    <bean id="student" class="com.stringzhua.pojo.Student">
        <constructor-arg type="java.lang.String" value="晞冉"></constructor-arg>
        <constructor-arg type="int" value="18"></constructor-arg>
    </bean>

Test.java

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
Student student = (Student) applicationContext.getBean("student");
System.out.println(student);

实现:构造注入javabean对象

applicationContext.xml

<!--    &lt;!&ndash;    ==构造注入javabean==&ndash;&gt;-->
<bean id="daoImpl" class="com.stringzhua.dao.UserDaoImpl"></bean>

<bean id="serviceImpl" class="com.stringzhua.service.UserServiceImpl">
  <constructor-arg name="dao" ref="daoImpl"></constructor-arg>
</bean>

<bean id="controllerImpl" class="com.stringzhua.controller.UserControllerImpl">
  <constructor-arg name="serivce" ref="serviceImpl"></constructor-arg>
</bean>

Test.java

ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
//        Student student = (Student) applicationContext.getBean("student");
//        System.out.println(student);

IUserController controller = (IUserController) applicationContext.getBean("controllerImpl");
controller.add();

Spring常见面试题

Spring 框架的基本理解

  • 关键字: 核心思想IOC\AOP、作用(解耦、简化),简单描述框架组成
  • Spring 框架是一款轻量级的开发框架,核心思想是 IOC(控制反转)AOP(面向切面编程) 为java 应用程序开发提供组件管理服务,用于组件之间的解耦,以及简化第三方JavaEE中间件技术的使用(jms、任务调度、缓存、orm 框架),是一个基础架构型的开发框架
  • Spring框架包括: IOC容器、Validation 数据校验、AOP面向切面编程、Transactions 事务管理、SpringJDBC 、Spring MVC框架、以及各类第三方JavaEE 中间件技术集成

Spring 框架由哪些模块组成?

  • 关键字: 官方文档描述,由7个模块组成
  • Spring framwork 根据官方文档的描述,主要包括以下常用5个模块:
    1. Core:核心模块 包括: IoC Container(loc容器),Events(事件通知机制),Resources(资源加载机制),118n(国际化),Validation(数据校验),Data Binding(数据绑定),Type Conversion(类型转换),spEl(spring表达式),AOP(面向切面编程);
    2. Testing:测试模块 包括: Mock Objects(测试模拟对象),TestContext Framework(测试框架),Spring MVC Test(用于测试Spring MVC),WebTestClient(用于测试WebClient 、Restful、Webflux等)
    3. Data Access:数据访问模块 包括:Transactions (事务管理),Dao Support (统一的 Data Access Object DAO 模式封装),jdbc(spring 对于 jdbc 的操作封装),O/R Mapping( spring 对于对象关系映射框架的封装,例如 hibernate 等框架)等;
    4. Web servlet:基于servlet的web应用开发 包括: Spring Mvc( Spring 基于 Mvc 模式设计封装的Web 框架), WebSocket(spring集成 websocket,websocket 是一个服务器与客户端双向通信的技术)等;
    5. Integration:企业级系统集成模块(不同系统之间的交互集成) 包括∶ remoting(spring 用于在分布式系统中进行远程服务调用的通讯框架)

Spring IOC的理解

  • 关键字: IOC 名词解释,作用是解耦,使用IOC容器管理项目组件之间的耦合关系
  • IOCInversion of control,中文释义:控制反转)是 Spring 框架的核心思想之一,主要用于解耦。IOC 是指将创建对象的控制权转移给 Spring 框架进行管理。由spring框架根据配置 文件或注解等方式,创建Bean对象并管理各个 Bean 对象之间的依赖关系。使对象之间形成松散耦合的关系,实现解耦 。
    • 控制:指的是对象创建(实例化、管理)的权力
    • 反转:控制权交给外部环境( Spring 框架、IoC 容器 )

Spring IOC容器的理解

  • 关键字: IOC 容器的作用、存储形式、初始化过程
  • IOC 通常被理解为 IOC Container 容器,IOC 容器其实就是一个 Map,key 是每个bean对象的ID,value 是 bean 对象本身。IOC 容器负责创建 bean 对象并管理 bean 的生命周期。并且根据配置好配置文件或注解,管理 ioc 容器中的每个bean,以及根据bean之间的依赖关系,完成bean之间的注入
  • IOC 容器属于Spring core模块,用来创建和管理bean,默认使用单例的方式将bean存储在 DefaultListableBeanFactory类的beanDefinitionMap中(一个 ConcurrentHashMap 类型的Map集合)
  • IOC 容器使用 ConcurrentHashMap 集合存储了 BeanDefinition 对象,该对象封装了 Spring 对一个 Bean 所有配置信息,包括:类名属性构造方法参数依赖是否延迟加载是否是单例等配置信息

Spring DI的理解

  • DIdependecy inject,中文释义:依赖注入)是对 IOC 概念的不同角度的描述,是指应用程序在运行时,每一个 bean 对象都依赖 IOC 容器注入当前 bean 对象所需要的另外一个 bean 对象。(例如在 mbatis整合 spring 时,SqlSessionFactoryBean 依赖 ioc 容器注入一个 DataSource 数据源 bean )

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2231060.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

纯享受 : 力扣:234 回文链表

BLG牛逼 – 奖励自己一道题 描述&#xff1a; 给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为 回文链表 。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例&#xff1a; 何解&#xff1f; 1、所谓 回文 就是正读反读都一样&…

开源项目-投票管理系统

哈喽,大家好,今天主要给大家带来一个开源项目-投票管理系统 投票管理系统主要有首页,发起投票,管理投票,参与投票,查看投票等功能 首页 为用户提供了一键导航到各个功能模块的便捷途径。 新增投票 用户可以在此轻松创建新的投票活动,设置投票主题、选项等信息。 管理…

系统架构图设计(行业领域架构)

物联网 感知层&#xff1a;主要功能是感知和收集信息。感知层通过各种传感器、RFID标签等设备来识别物体、采集信息&#xff0c;并对这些信息进行初步处理。这一层的作用是实现对物理世界的感知和初步处理&#xff0c;为上层提供数据基础网络层&#xff1a;网络层负责处理和传输…

APP获取用户的三大法则

APP内容&#xff0c;提升APP吸引力和用户留存率 A. 用户研究深化 1. **深入用户行为分析**&#xff1a; - 用户使用路径分析 - 用户行为模式识别 - 用户流失点分析 2. **定性研究与定量研究结合**&#xff1a; - 进行深度访谈和焦点小组讨论 - 利用数据分析用…

QT——串口调试助手

目录 1.QSerialPort类包含了很多有关串口的API 2.实现串口的打开 2.1 方法一&#xff1a;通过函数实现 2.2 方法二&#xff1a;在ui界面右下角实现 3. 实现定时发送 3.1类的私有成员中添加定时器QTimer timer并去构造函数中初始化它 3.2帮助文档中有QTimer类相关的说明 …

全自动一键批量创建站群网站插件 | Z-BlogPHP 堆词起站工具

在当今竞争激烈的数字营销世界&#xff0c;如何快速提升网站曝光率和流量&#xff1f;答案就是智能站群系统。 本文将结合实际效果&#xff0c;介绍一款功能强大的站群系统&#xff0c;重点讲述其堆词功能、泛目录管理、一键批量创建、内容转码、自定义标签和GPT内容生成与发布…

计算机毕业设计Spark+大模型知识图谱中药推荐系统 中药数据分析可视化大屏 中药爬虫 机器学习 中药预测系统 中药情感分析 大数据毕业设计

温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 温馨提示&#xff1a;文末有 CSDN 平台官方提供的学长联系方式的名片&#xff01; 作者简介&#xff1a;Java领…

Linux云计算 |【第五阶段】CLOUD-DAY7

主要内容&#xff1a; 在kubernetes平台上理解掌握各种控制器的用法&#xff1a;掌握kubectl管理命令、掌握POD原理、掌握集群调度的规则、熟悉控制器资源文件&#xff1b; 一、kubectl 常用命令 Kubectl是用于控制Kubernetes集群的命令行工具&#xff1b; - 格式&#xff1…

json-server的使用(根据json数据一键生成接口)

一.使用目的 在前端开发初期&#xff0c;后端 API 可能还未完成&#xff0c;json-server 可以快速创建模拟的 RESTful API&#xff0c;帮助前端开发者进行开发和测试。 二.安装 npm install json-server //局部安装npm i json-server -g //全局安装 三.使用教程 1.准备一…

在VS中安装chatGPT

2、在VSCode中打开插件窗口 3、输入ChatGPT 4、这里有个ChatGPT中文版&#xff0c;就它了 5、安装 6、这时候侧边栏多了一个chatGPT分页图标&#xff0c;点击它 7、打个招呼 8、好像不行 9、看一下细节描述 10、根据要求按下按下快捷键 Ctrl Shift P 11、切换成国内模式 12、…

# linux从入门到精通-从基础学起,逐步提升,探索linux奥秘(十九)--mysql数据库基本操作

linux从入门到精通-从基础学起&#xff0c;逐步提升&#xff0c;探索linux奥秘&#xff08;十九&#xff09;–mysql数据库基本操作 一、MySQL的基本操作&#xff08;1&#xff09;&#xff08;难点&#xff09; 1、名词介绍 以Excel文件举例&#xff1a; 数据库&#xff1a…

冒泡排序,快速排序讲义

冒泡排序 基本原理&#xff1a;对存放原始数据的数组&#xff0c;按从前往后的方向进行多次扫描&#xff0c;每次扫描称为一趟。当发现相邻的两个数据次序和排序要求的大小次序不符合的时候&#xff0c;即将这两个数据进行互换。如果从小到大排序&#xff0c;这时&#xff0c;…

智能语音助手:开启智能交互的新时代

随着人工智能和自然语言处理技术的进步&#xff0c;智能语音助手已经逐渐成为日常生活中的一部分。无论是手机上的虚拟助手、智能音箱&#xff0c;还是车载导航和智能家居控制系统&#xff0c;智能语音助手的应用越来越广泛&#xff0c;为用户提供了高效便捷的交互体验。通过语…

vue data变量之间相互赋值或进行数据联动

摘要&#xff1a; 使用vue时开发会用到data中是数据是相互驱动&#xff0c;经常会想到watch,computed&#xff0c;总结一下&#xff01; 直接赋值&#xff1a; 在 data 函数中定义的变量可以直接在方法中进行赋值。 export default {data() {return {a: 1,b: 2};},methods: {u…

uniapp ,微信小程序,滚动(下滑,上拉)到底部加载下一页内容

前言 小程序的内容基本都是滑动到底部加载下一页&#xff0c;这个一般都没有什么好用的组件来用&#xff0c;我看vant和uniapp的插件里最多只有个分页&#xff0c;没有滚动到底部加载下一页。再次做个记录。 效果预览 下滑到底部若是有下一页&#xff0c;则会自动加载下一页&…

【数据分享】2024年我国省市县三级的休闲娱乐设施数量(免费获取/18类设施/Excel/Shp格式)

KTV、棋牌室、音乐厅等休闲服务设施的配置情况是一个城市公共基础设施完善程度的重要体现&#xff0c;一个城市休闲服务设施种类越丰富&#xff0c;数量越多&#xff0c;通常能表示这个城市的公共服务水平越高&#xff01; 本次我们为大家带来的是我国各省份、各地级市、各区县…

Flarum:简洁而强大的开源论坛软件

Flarum简介 Flarum是一款开源论坛软件&#xff0c;以其简洁、快速和易用性而闻名。它继承了esoTalk和FluxBB的优良传统&#xff0c;旨在提供一个不复杂、不臃肿的论坛体验。Flarum的核心优势在于&#xff1a; 快速、简单&#xff1a; Flarum使用PHP构建&#xff0c;易于部署&…

【CSS in Depth 2 精译_056】8.4 CSS 的新特性——原生嵌套(Nesting)+ 8.5 本章小结

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 【第三部分 现代 CSS 代码组织】 ✔️【第八章 层叠图层及其嵌套】 ✔️ 8.1 用 layer 图层来操控层叠规则&#xff08;上篇&#xff09; 8.1.1 图层的定义&#xff08;上篇&#xff09;8.1.2 图层的…

Qt字符编码

目前字符编码有以下几种&#xff1a; 1、UTF-8 UTF-8编码是Unicode字符集的一种编码方式(CEF)&#xff0c;其特点是使用变长字节数(即变长码元序列、变宽码元序列)来编码。一般是1到4个字节&#xff0c;当然&#xff0c;也可以更长。 2、UTF-16 UTF-16是Unicode字符编码五层次…

分布式事务-SpringBoot集成Seata

1.本地事务和分布式事务概念 事务四大特性 原子性&#xff1a;事务不可再分一致性&#xff1a;数据改变前后&#xff0c;总量必须一致隔离性&#xff1a;事务之间相互隔离&#xff0c;互不干扰持久性&#xff1a;事务一旦提交&#xff0c;数据就会持久化到磁盘&#xff0c;不…