首页 > 其他分享 >spring整合框架

spring整合框架

时间:2023-02-23 23:34:20浏览次数:31  
标签:缓存 框架 spring bean liku 整合 标签 com

循环引用

BeanCurrentlyInCreationException

当A对象需要引用B对象,而B对象也需要A对象的时候就是双向,当spring属性填充为双向注入的时候叫做循环依赖,也叫做循环引用

spring提供了三级缓存存储完整的bean和半成品bean,用于解决循环引用的问题:

例如:userDao与userService双向注入

userService实例化对象,但尚未初始化,将半成品存储到三级缓存

userService属性注入,需要userDao,从缓存中获取,没有userDao

userDao实例化对象,尚未初始化,将userDao存储到三级缓存

userDao属性注入,需要userService,从三级缓存获取userService,userService从三级缓存移入二级缓存

userDao执行其他生命周期,最终为完整bean,存储到一级缓存,删除二三级缓存

userService注入userDao

userSerive执行其他生命周期,成为完整bean,存储到一级缓存,删除二三级缓存

常用的aware接口

接口名称回调方法作用
ServletContextAwaregetServletContext()注入servletContext对象
BeanFactoryAwaresetBeanFactory()注入beanFactory
BeanNameAwaresetBeanName()注入beanName
ApplicationContextAwaresetApplicationContext()注入applicationContext

spring整合mybatis

在bean的配置文件中添加bean:

<!--数据源对象-->
<bean id="dataSources" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
    <property name="url" value="jdbc:mysql://localhost:3306/4031"></property>
    <property name="username" value="root"></property>
    <property name="password" value="123456"></property>
</bean>
<!--配置SqlSessionFactoryBean,将SqlSessionFactory存储到spring容器-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
    <!--为SqlSessionFactory注入数据源-->
    <property name="dataSource" ref="dataSources"></property>
</bean>
<!--扫描指定包,产生Mapper对象存储到spring容器-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <!--注入需要扫描的包-->
    <property name="basePackage" value="com.liku.mapper"></property>
</bean>

由于是service层调用数据持久层,因此在service层我们添加一个属性,并调用mapper文件里面查询所有的方法:

public class UserServiceImpl implements UserService {
   private SysuserMapper mapper;

    public void setMapper(SysuserMapper mapper) {
        this.mapper = mapper;
    }

    @Override
    public void show() {
        mapper.selectAll().forEach(System.out::println);
    }
}

在bean中我们添加实例化service层的bean:

bean id="service" class="com.liku.service.impl.UserServiceImpl">
    <!--引用名称为类名的小写,不然会报没有这个bean异常-->
    <property name="mapper" ref="sysuserMapper"></property>
</bean>

上面要注意引用的需要是类名的小写,不然会报没有这个bean的异常

接下来获取service对象,并且调用show方法就可以对进行数据库的查询。

上面的操作相关类有四个:

SqlSessionFactoryBean:配置创建SqlSessionFactory的bean工厂,用于产生SqlSessionFactory

MapperScannerConfigurer:配置MapperScannerConfigurer用于扫描指定包下面的mapper,并且注册BeanDefinition

MapperFactoryBean:Mapper的FactoryBean,调用getObject()获得指定的Mapper

ClassPathMapperScanner:修改自动注入状态 definition.setAutowireMode(2),MapperFactoryBean中的setSqlSessionFactory会自动注入进去

读取数据库配置文件连接数据库

新建配置文件【jdbc.properties】

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/4031
user=root
pwd=123456

在bean的配置文件beans属性中添加:

xmlns:context="http://www.springframework.org/schema/context"

并且添加上对应的xsi:schemaLocation

http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd

加载配置文件:

<context:property-placeholder location="classpath:jdbc.properties"/>

通过el表达式为数据源对象注入值

<bean id="dataSources" class="com.alibaba.druid.pool.DruidDataSource">
    <property name="driverClassName" value="${driver}"></property>
    <property name="url" value="${url}"></property>
    <property name="username" value="${user}"></property>
    <property name="password" value="${pwd}"></property>
</bean>

完整beans的配置文件如下:

<?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"
       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">
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <!--数据源对象-->
    <bean id="dataSources" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${driver}"></property>
        <property name="url" value="${url}"></property>
        <property name="username" value="${user}"></property>
        <property name="password" value="${pwd}"></property>
    </bean>
    <!--配置SqlSessionFactoryBean,将SqlSessionFactory存储到spring容器-->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--为SqlSessionFactory注入数据源-->
        <property name="dataSource" ref="dataSources"></property>
    </bean>
    <!--扫描指定包,产生Mapper对象存储到spring容器-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--注入需要扫描的包-->
        <property name="basePackage" value="com.liku.mapper"></property>
    </bean>
    <bean id="service" class="com.liku.service.impl.UserServiceImpl">
        <!--引用名称为类名的小写,不然会报没有这个bean异常-->
        <property name="mapper" ref="sysuserMapper"></property>
    </bean>
</beans>

实例化service层调用方法,查询数据库成功

外部命名空间标签的执行流程

将自定义标签的约束与物理约束文件、网络约束名称的约束 以键值对形式存储到一个spring.schemas文件里,将该文件存储在类加载器路径的META-INF里,spring会自动加载;

将自定义命名空间的名称 与 自定义命名空间的处理器映射关系 以键值对形式存到一个叫spring.handler文件中;

准备好NameSpaceHandler,如果命名空间只有一个标签,那么直接在parse方法中进行解析即可,一般结果就是注册该标签对应的BeanDefinition;如果有多个标签,那么可以在init方法中为每个标签注册一个BeanDefinitionParser,在执行parse方法的时候根据不同的标签,解析成不同的BeanDefinitionParser

通过自定义标签,向spring容器中自动注入一个BeanPostProcessor

分析:

确定命名空间名称、schema虚拟路径、标签名称

编写schema约束文件xx.xsd

在类加载路径下创建META-INF目录,编写约束映射文件spring.schemas和处理器映射文件spring.handlers

编写命名空间处理器xxNameSpaceHandler,在init方法中注册xxBeanDefinitionParser

编写标签的解析器xxBeanDefinitionParser,在parse方法中注册xxBeanPostProcessor

编写xxBeanPostProcessor

在applicationContext.xml配置文件中引入命名空间

在applicationcontext.xml中使用自定义标签

实现上面的步骤:

第一步:创建xsd文件【liku.xsd】,里面设置标签和命名空间

<?xml version="1.0"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
           targetNamespace="http://www.liku.com/lulu">
    <xs:element name="myElement-liku"></xs:element>
</xs:schema>

第二部:创建META-INF目录,并创建约束映射文件:

spring.schemas:

http\://www.liku.com/lulu/lulu.xsd=com/liku/config/liku.xsd

第三步:创建命名空间处理器LuNameSpaceHandler类,继承NamespaceHandlerSupport,重写init方法:

public class LuNamspaceHandler extends NamespaceHandlerSupport {
    @Override
    public void init() {
        //初始化标签解析器
        this.registerBeanDefinitionParser("myElement-liku",new LuBeanDefinitionParser());
    }
}

第四步:创建标签解析器LuBeanDefinitionParser实现BeanDefinitionParser,重写里面的方法:

public class LuBeanDefinitionParser implements BeanDefinitionParser {
    @Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        System.out.println("我是自定义");
        BeanDefinition definition=new RootBeanDefinition();
        definition.setBeanClassName("com.liku.entity.MyBeanFactoryPostProcessor");
        parserContext.getRegistry().registerBeanDefinition("beanPostProcessor",definition);
        return definition;
    }
}

第五步:在META-INF下创建spring.handlers:

http\://www.liku.com/lulu=com.liku.handler.LuNamspaceHandler

在ApplicationContext.xml中添加自定义标签:

xmlns:lulu="http://www.liku.com/lulu"
http://www.liku.com/lulu
http://www.liku.com/lulu/lulu.xsd

引入标签:

<lulu:myElement-liku></lulu:myElement-liku>

xml引入之后上半部分结构如下:

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:lulu="http://www.liku.com/lulu"
       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
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.liku.com/lulu
       http://www.liku.com/lulu/lulu.xsd">
    <lulu:myElement-liku></lulu:myElement-liku>

bingo!案例完成!

标签:缓存,框架,spring,bean,liku,整合,标签,com
From: https://www.cnblogs.com/Liku-java/p/17149869.html

相关文章

  • 35-DRF框架-生成接口文档
    #注意:只能是ApiView及子应用#1.安装coreapi库#2.主应用中配置路径url(r'^docs/',include_docs_urls(title='接口文档'))#3.主应用中settings.py配置......
  • SpringBoot 集成 MybatisPlus
    MybatisPlus是Mybatis的升级版本,是对Mybatis的简化,因为他们的口号就是“为简化开发而生”。1、创建数据表CREATETABLE​​User​​(​​id​​INTNOTNULL,​​us......
  • 34-DRF框架-视图及扩展类
    #GenericAPIView继承自APIVIew,增加了对于列表视图和详情视图可能用到的通用支持方法。#常用属性'''queryset列表视图的查询集serializer_class视图使......
  • 33-DRF框架-反序列化使用
    #增加修改#把参数转成model对象,操作数据库#步骤:#1.创建序列化对象data传递参数进行验证#2.is_validate()函数验证#3.通过可以使用validated......
  • 深入学习jquery源码之继承框架的实现
    深入学习jquery源码之继承框架的实现继承框架的实现实现自己的extend方法/*SimpleJavaScriptInheritance*ByJohnResighttp://ejohn.org/*MITLicensed.*///Insp......
  • Spring Boot 之Application.properties配置大全
    前几期,我们讲到了SpringBoot的框架,动手操作过的人,应该都还记得,并且觉得确实简化了很多,那么对于其中application.properties的配置文件,其中的配置信息有哪些,现在小编这几天......
  • vue总结与整合(走过路过,千万不要错过,进来看看,全篇皆是精华)
    vue总结与整合vue简介 vue是一款用于构建用户界面的js框架,基于标准HTML、CSS和JavaScript构建,并提供了一套声明式的、组件化的编程模型,帮助开发者高效地开发用户界面。......
  • Spring简介
     Spring简介官网地址:https://spring.io/ 一、Spring旗下的众多项目:Projects:Fromconfigurationtosecurity,webappstobigdata—whatevertheinfrastructu......
  • springboot集成flume实现多系统日志收集
    本次demo实现的功能:使用flume框架收集目标工程的日志信息,并发送到kafka,最终完成kafka的消费1、配置工程配置logback:<!--此处为flume日志采集的配置--><appende......
  • 32-DRF框架-序列化器ModelSerializer
    #如果我们想要使用序列化器对应的是Django的模型类,DRF为我们提供了ModelSerializer模型类序列化器来帮助我们快速创建一个Serializer类创建modelserializer序列化器#......