Java后端07(Spring未完成)

这篇具有很好参考价值的文章主要介绍了Java后端07(Spring未完成)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Spring

​ 涉及的设计模式:单例模式,简单工厂模式,代理模式,观察者模式,反射,注解。。。。。

Spring配置文件文件头

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd 
       http://www.springframework.org/schema/aop 
       http://www.springframework.org/schema/aop/spring-aop.xsd">
</beans>

IOC 控制反转 ---- 将创建对象的权力由开发者交 给 Spring(缓解对象和对象之间的耦合度)

​ 在传统模式下,对象的创建和赋值,都是由开发者自己手动完成,事实情况下,开发者只关心如何获取赋值好的对象,但是并不希望自己手动进行创建对象和赋值的事情(spring中所有的对象都是从实例工厂中自动创建,涉及到简单工厂模式)

IOC底层原理

  1. xml解析(负责读取配置文件中 Bean 的相关信息)
  2. 简单工厂模式(借助 BeanFactory 完成对象的实例化和返回)
  3. 反射(不使用 new 创建对象的根本原因)

简单工厂模式

优点:

  1. 设计与实现分离(开发者不需要关心对象是如何创建出来的)
  2. 如果要拓展业务,并不会影响之前的业务,只需要拓展子类即可

IOC容器的两种实现方式

  1. BeanFactory:是Spring内部使用的接口,不建议给开发人员使用,该容器加载配置文件时,并不会创建响应对象,当开发者尝试获取对象的时候,才会创建对象(类似懒汉模式,具有延迟加载的特性)
  2. ApplicationContext:BeanFactory的子接口,一般由开发人员使用,该容器在加载配置文件的时候,就会创建对象(类似饿汉模式,不会出现并发安全问题,线程安全)

DI 依赖注入 ---- 在你配置好 bean 的情况下,由 Spring 帮你完成对象的赋值

优点:

  1. 实现了接口和实现的分离
  2. 组件化的思想,分离关注点,使用接口时,不再关注实现

Spring 的 bean 管理

⭐Bean的生命周期

  1. 常规五步生命周期

    ​ 通过构造器创建 bean 实例 => 通过反射调用 setter 方法完成属性赋值 => 调用 bean 的初始化方法 => 获取 bean 实例 => 当容器关闭的时候, 调用 bean 的销毁方法

  2. 完整七步生命周期

    ​ 通过构造器创建 bean 实例 => 通过反射调用 setter 方法完成属性赋值 => 在 bean 初始化之前调用后置处理器 => 调用 bean 的初始化方法 => 在 bean初始化之后调用后置处理器 => 获取 bean 实例 => 当容器关闭的时候, 调用 bean 的销毁方法

    // 后置处理器 Demo
    public class MyPostProcessor implements BeanPostProcessor {
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("初始化之前调用的处理器");
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.println("初始化之后调用的处理器");
            return bean;
        }
    }
    
bean的自动装配

​ 自动装配:根据 bean 的 name 或者 type 实现自动装配

  1. byName 根据属性名称自动注入(注入的 bean 名称要跟属性名称保持一致)
  2. byType 根据属性的类型自动注入
<!-- byName 方式 自动装配 bean-->
<!-- person 对象再实例化的时候,需要注入 dog 属性,而 dog 属性对应的应该是一个 Dog 类对象的内存地址-->
<!-- byName 会根据你的成员变量名称,找到匹配的 id 的 bean-->
<bean id="person" class="com.iweb.entity.Person" autowire="byName" />
<bean id="dog" class="com.iweb.entity.Dog" />

<!--    byType 方式 根据成员变量的类型,自动装配 id 不需要和成员变量匹配-->
<bean id="person" class="com.iweb.entity.Person" autowire="byType" />
<bean id="dog" class="com.iweb.entity.Dog" />

<!--    导入外部配置文件-->
<context:property-placeholder location="db.properties" />
<!--    在 spring 中加载外部配置文件 使用${}传参 以 druid 连接池为例-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${jdbc.driver}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
</bean>

bean创建(IOC)

  1. 基于xml的配置方式

    结构分析<bean id="person" class="com.iweb.entity.Person" scope="prototype"/>

    id 对象的唯一标识,通过 id 获取 bean 实例

    class 对象所属类的完整路径,用于提供给 spring 借助反射完成的对象创建

    scope 表示单/多实例模式

    <!--    属性注入-->
    <bean id="dog" class="com.iweb.entity.Dog">
        <property name="name" value="dog01"/>
        <property name="type" value="dogType01"/>
    </bean>
    
    <!--    构造注入,利用构造函数实现注入        未解决,爆红!!!!!!!!-->
    <bean id="dog" class="com.iweb.entity.Dog">
        <constructor-arg name="name" value="dog01"/>
    </bean>
    
    <!--    空值注入,手动注入空值-->
    <bean id="dog" class="com.iweb.entity.Dog">
        <property name="name"><null/></property>
    </bean>
    
    <!--    特殊符号注入-->
    <bean id="dog" class="com.iweb.entity.Dog">
        <property name="name">
            <value><![CDATA[(-.-)]]></value>
        </property>
    </bean>
    
    <!--    外部 bean 注入(引用绑定)-->
    <bean id="dog" class="com.iweb.entity.Dog">
        <property name="name" value="dog01" />
        <property name="type" value="type01" />
    </bean>
    <bean id="person" class="com.iweb.entity.Person">
        <property name="dog" ref="dog" />
    </bean>
    
    <!--    内部 bean 注入(只能在某一个 bean 的内部访问它,其他 bean 无法访问内部bean)-->
    <bean id="person" class="com.iweb.entity.Person">
        <property name="dog">
            <bean class="com.iweb.entity.Dog">
                <property name="name" value="dog01" />
                <property name="type" value="type01" />
            </bean>
        </property>
    </bean>
    
    <!--    级联赋值-->
    <bean id="person" class="com.iweb.entity.Person">
        <property name="dog" ref="dog" />
        <property name="dog.type" value="type01" />
        <property name="dog.name" value="dog01" />
    </bean>
    <bean id="dog" class="com.iweb.entity.Dog" />
    
    <!--    集合注入 => 数组, list, map, set-->
    <bean id="person" class="com.iweb.entity.Person">
    <!--        数组注入-->
        <property name="hobbiesArray">
            <array>
                <value>games</value>
                <value>coding</value>
            </array>
        </property>
    <!--        list集合注入-->
        <property name="hobbiesList">
            <list>
                <value>games</value>
                <value>coding</value>
            </list>
        </property>
    <!--        set集合注入-->
        <property name="hobbiesSet">
            <set>
                <value>games</value>
                <value>coding</value>
            </set>
        </property>
    <!--        map集合注入-->
        <property name="hobbiesMap">
            <map>
                <entry key="games" value="游戏" />
                <entry key="coding" value="编码" />
            </map>
        </property>
    </bean>
    
    <!--    Spring中管理了两种Bean
                1. 普通Bean 在配置文件中定义的类型,与返回类型保持一致
                2. FactoryBean 在配置文件中定义的类型和返回的类型可以不一致
    		表面上是 factoryBeanDemo 类, 实际上是该类下的 dog 类
    		原理类似于 @Configuration 和 @Bean 注解
    -->
    <bean id="factoryBeanDemo" class="com.iweb.entity.FactoryBeanDemo" />
    
  2. 基于注解方式

    Spring 对 bean 的管理提供了几种注解,注解的功能是一致的,都用来注册bean,但是注解本身所代表的含义不同

    注解 含义
    @Component 普通注解
    @Service 业务层注解
    @Controller 控制器注解(SpringMVC使用)
    @Repostiory DAO层注解(如果是 mybatis 一般会使用 @Mapper 或者在 springboot 中使用 @MapperScan)
    @Configuration 配置类注解
    @Bean 配置类 bean 返回注解
    @Qualifier 在使用了@AutoWired 注解的前提下,指定目标 name 所对应的 bean 进行注入
    @AutoWired 根据类型自动装配(注入)
    @Resource 可以选择根据类型,或者 name 进行注入,在注入目标为接口类型的时候,如果接口只有一个实现类,可以直接通过类型注入,如果接口有多个实现类,可以配置 name 属性, 实现通过 name 指定注入
    @Value 直接注入
    @ComponentScan 注解扫描注解

    @AutoWired 和 @Resource 区别:

    1. @AutoWired 来自于 spring @Resource 来自于 jdk 原生
    2. @AutoWired 是根据类型自动获取,如果想根据 name 获取,需要 @Qualifier 协助
    3. @Resource 是根据类型或 name 获取,如果提供 name 属性,则按照 name 获取,如果不提供则按照 type 获取

    举个栗子:

    // service层代码
    // 等价于 <bean id="userService" class="com.iweb.service.Impl.UserServiceImpl" />
    @Service(value = "userService")
    public class UserServiceImpl implements UserService {
        @Override
        public int add() {
            System.out.println("UserService => add()");
            return 0;
        }
    }
    
    // mapper层代码,定义两个相同的子类,注册bean
    @Repository(value = "userMapper01")
    public class UserMapperImpl01 implements UserMapper {
        @Override
        public int add() {
            System.out.println("UserMapperImpl01 => add()");
            return 0;
        }
    }
    
    @Repository(value = "userMapper02")
    public class UserMapperImpl02 implements UserMapper {
        @Override
        public int add() {
            System.out.println("UserMapperImpl02 => add()");
            return 0;
        }
    }
    

AOP面向切面编程

​ AOP面向切面编程,但是AOP不等于 SpringAOP,SpringAOP 只是 AOP的一种实现方式而已,切面的内容和主业务逻辑是没有关系的,不管切面的数量有多少,都不会影响也不应该影响主业务的运行

注解方式配置AOP(底层:代理模式)

⭐要给AOP文件添加 @Component@Aspect注解

  1. Before前置增强

    在目标方法钱植入增强处理

    @Before(value = "execution(* com.iweb.mapper.UserMapper.add(..))")
    public void before(JoinPoint joinPoint){
        System.out.println("UserProxy => before()");
        System.out.println("准备执行" + joinPoint.getTarget() + "的方法:" + joinPoint.getSignature().getName());
    }
    
  2. afterReturning后置增强

    在目标方法正常执行(无异常)后植入增强处理

    @AfterReturning(value = "execution(* com.iweb.mapper.UserMapper.add(..))", returning = "returnValue")
    public void afterReturning(JoinPoint joinPoint,Object returnValue){
        System.out.println("UserProxy => afterReturning().");
        System.out.println(joinPoint.getTarget() + "的方法" + joinPoint.getSignature().getName() + "的返回值为" + returnValue);
    }
    
  3. afterThrowing异常抛出增强

    在目标方法抛出异常的时候植入增强处理

    @AfterThrowing(value = "execution(* com.iweb.mapper.UserMapper.add(..))",throwing = "exception")
    public void afterThrowing(JoinPoint joinPoint,Exception exception){
        System.out.println("UserProxy => afterThrowing()");
        System.out.println("调用" + joinPoint.getSignature().getName() + "方法发生异常" + exception.getMessage());
    }
    
  4. after最终增强

    无论方法是否抛出异常,都会在目标方法之后植入增强处理,类似于异常处理机制中 finally 块的作用,一般用于释放资源

    @After(value = "execution(* com.iweb.mapper.UserMapper.add(..))")
    public void after(JoinPoint joinPoint){
        System.out.println("UserProxy => after()");
        System.out.println("调用" + joinPoint.getSignature().getName() + "方法结束");
    }
    
  5. around环绕增强

    在目标方法前后都可以植入增强处理,功能最强大的增强处理,可以获取或修改目标方法的参数,返回值,甚至可以控制目标方法是否执行文章来源地址https://www.toymoban.com/news/detail-632502.html

    @Around(value = "execution(* com.iweb.mapper.UserMapper.add(..))")
    public Object around(ProceedingJoinPoint joinPoint){
        System.out.println("UserProxy => around()");
        try{
            System.out.println("准备执行" + joinPoint.getTarget() + "方法" + joinPoint.getSignature().getName());
            // 获取目标方法的返回值
            Object result = joinPoint.proceed();
            System.out.println("环绕增强处理之前的方法返回值为:" + result);
            return (Integer)result + 10086;
        }catch(Throwable e){
            e.printStackTrace();
            return null;
        }
    }
    

到了这里,关于Java后端07(Spring未完成)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【设计模式-07】Composite组合模式

    定义抽象节点类 Node ,定义抽象方法 public abstract void print(); 定义叶子节点类 LeafNode ,继承Node节点,实现 print() 抽象方法,叶子节点没有子节点 定义子节点类 BranchNode ,继承Node节点,实现 print() 抽象方法,子节点既可以有子节点,也又可以有叶子节点 定义一个树状目录结构

    2024年01月18日
    浏览(50)
  • Java 设计者模式以及与Spring关系(四) 代理模式

    目录 简介: 23设计者模式以及重点模式 代理模式(Proxy Pattern) 静态代理示例 spring中应用 动态代理 1.基于JDK的动态代理 target.getClass().getInterfaces()作用 内名内部类写法(更简洁,但不推荐) 2.基于CGLIB实现 spring中应用 本文是个系列一次会出两个设计者模式作用,如果有关联就三

    2024年01月23日
    浏览(48)
  • java Spring中使用到的设计模式

    单例模式(Singleton Pattern)是java中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一对象的方式,可以直接

    2024年02月16日
    浏览(63)
  • Java 设计者模式以及与Spring关系(七) 命令和迭代器模式

    本文是个系列一次会出两个设计者模式作用,如果有关联就三个,除此外还会讲解在spring中作用。 23设计者模式以及重点模式 我们都知道 设计者模式 有 3 类 23 种设计模式,标红是特别重要的设计者模式建议都会,而且熟读于心,标蓝是指其次重要建议也要明白。 (1)创建

    2024年01月24日
    浏览(36)
  • Java 设计者模式以及与Spring关系(六) 装饰和模版方法模式

    本文是个系列一次会出两个设计者模式作用,如果有关联就三个,除此外还会讲解在spring中作用。 23设计者模式以及重点模式 我们都知道 设计者模式 有 3 类 23 种设计模式,标红是特别重要的设计者模式建议都会,而且熟读于心,标蓝是指其次重要建议也要明白。 (1)创建

    2024年01月24日
    浏览(41)
  • Java后端07(Spring)

    ​涉及的设计模式:单例模式,简单工厂模式,代理模式,观察者模式,反射,注解。。。。。 ​在传统模式下,对象的创建和赋值,都是由开发者自己手动完成,事实情况下,开发者只关心如何获取赋值好的对象,但是并不希望自己手动进行创建对象和赋值的事情(sprin

    2024年02月13日
    浏览(36)
  • ༺༽༾ཊ—设计-七个-07-原则-模式—ཏ༿༼༻

    第七原则:迪米特职责         类与类之间的耦合度尽可能低 换言之,我们可以理解成———只与直接朋友说话,不跟陌生人说话 直接朋友: 通过方法传参传进来的朋友, 类自己的字段, 构造函数进来的也是直接朋友, 总的来说,类直接能接触到的朋友就是直接朋友 而

    2024年01月16日
    浏览(36)
  • 【设计模式】使用原型模式完成业务中“各种O”的转换

    原型模式是一种非常简单易懂的模型,在书上的定义是这样的: Specify the kinds of objects to create using a prototypical instance,and create new objects by copying this prototype. 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 通俗的讲,就是有一个现成的对象,我们通过复

    2024年02月07日
    浏览(80)
  • 【设计模式与范式:行为型】71 | 命令模式:如何利用命令模式实现一个手游后端架构?

    设计模式模块已经接近尾声了,现在我们只剩下 3 个模式还没有学习,它们分别是:命令模式、解释器模式、中介模式。这 3 个模式使用频率低、理解难度大,只在非常特定的应用场景下才会用到,所以,不是我们学习的重点,你只需要稍微了解,见了能认识就可以了。 今天

    2024年02月09日
    浏览(40)
  • spring的设计模式----简单工厂模式

    spring中IoC 控制反转,底层是工厂模式。 工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。 工厂模式提供了一种将对象的实例化过程封装在工厂类中的方式。通过使用工厂模式,可以将对象的

    2024年02月17日
    浏览(46)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包