Spring使用xml方式整合第三方框架流程詳解
一、概述
xml整合第三方框架有兩種整合方案:
- 不需要自定義名空間,不需要使用Spring的配置文件配置第三方框架本身內(nèi)容,例如:MyBatis;
- 需要引入第三方框架命名空間,需要使用Spring的配置文件配置第三方框架本身內(nèi)容,例如:Dubbo。
Spring整合MyBatis,之前已經(jīng)在Spring中簡單的配置了SqlSessionFactory, 但是這不是正規(guī)的整合方式,MyBatis提供了mybatis-spring.jar專門用于兩大框架的整合。 Spring整合MyBatis的步驟如下:
- 導(dǎo)入MyBatis整合Spring的相關(guān)坐標;(請見資料中的pom.xml)
- 編寫Mapper和Mapperxml;
- 配置SqlSessionFactoryBean和MapperScannerConfigurer;
- 編寫測試代碼
二、代碼演示
①:原始方式使用Mybatis
1.創(chuàng)建BookMapper類和BookMapper.xml文件
package com.tangyuan.mapper; import com.tangyuan.pojo.Book; import java.util.List; public interface BookMapper { List<Book> findAll(); }
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.tangyuan.mapper.BookMapper" > <select id="findAll" resultType="com.tangyuan.pojo.Book"> select * from t_book </select> </mapper>
2.在mybatis-config.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> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/bookshop?useSSL=false"></property> <property name="username" value="root"></property> <property name="password" value="1234"></property> </dataSource> </environment> </environments> <mappers> <package name="com.tangyuan.mapper"/> </mappers> </configuration>
3.編寫原始測試代碼
package com.tangyuan.test; import com.tangyuan.mapper.BookMapper; import com.tangyuan.pojo.Book; import org.apache.ibatis.annotations.Mapper; 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 java.io.IOException; import java.io.InputStream; import java.util.List; public class MyBatisTest { public static void main(String[] args) throws Exception { //讀取配置文件 //靜態(tài)工廠方法方式 InputStream resource = Resources.getResourceAsStream("mybatis-config.xml"); //設(shè)置構(gòu)造器 //無參構(gòu)造實例化 SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder(); //構(gòu)建工廠 //實例工廠方法 SqlSessionFactory build = builder.build(resource); SqlSession sqlSession = build.openSession(); BookMapper mapper = sqlSession.getMapper(BookMapper.class); List<Book> all = mapper.findAll(); for (Book a:all){ System.out.println(a); } } }
1.在pom文件引入依賴
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.7</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>5.3.20</version> </dependency>
2.在主xml文件中進行文件的配置
<!--1.配置SqlSessionFactoryBean,作用將SqlSessionFactory存儲到Spring容器--> <bean class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> </bean> <!--配置數(shù)據(jù)源信息--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> <property name="url" value="jdbc:mysql://localhost:3306/bookshop"></property> <property name="username" value="root"></property> <property name="password" value="1234"></property> </bean> <!--2.掃描指定的包,產(chǎn)生Mapper對象存儲到Spring容器--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.tangyuan.mapper"></property> </bean>
3.在需要方法的類上調(diào)用方法
//需要Mapper,直接注入Mapper和提供set方法 private BookMapper bookMapper; public void setBookMapper(BookMapper bookMapper) { this.bookMapper = bookMapper; } //輸出集合 @Override public void show(){ List<Book> all = bookMapper.findAll(); all.forEach(System.out::println); }
4.在xml文件上進行bean的配置
<bean id="userService" class="com.tangyuan.service.impl.UserServiceImpl"> <property name="bookMapper" ref="bookMapper"></property> </bean>
5.測試
//創(chuàng)建ApplicationContext,加載配置文件,實例化容器 ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml"); IUserService userService = (IUserService) applicationContext.getBean("userService"); userService.show();
三、Spring整合MyBatis的原理剖析
整合包里提供了一個SqlSessionFactoryBean和一個掃描Mapper的配置對象,SqlSessionFactoryBean一旦被實例化, 就開始掃描Mapper并通過動態(tài)代理產(chǎn)生Mapper的實現(xiàn)類存儲到Spring容器中。相關(guān)的有如下四個類:
- SqlSessionFactoryBean:需要進行配置, 用于提供SqlSessionFactory;
- MapperScannerConfigurer:需要進行配置,用于掃描指定mapper注冊BeanDefinition;
- MapperFactoryBean:Mapper的FactoryBean, 獲得指定Mapper時調(diào)用getObject方法;
- ClassPathMapperScanner:definition.setAutowireMode(2) 修改了自動注入狀態(tài),所以 MapperFactoryBean中的setSqlSessionFactory會自動注入進去。
Spring整合其他組件時就不像MyBatis這么簡單了, 例如Dubbo框架在于Spring進行整合時, 要使用Dubbo提供的命名空間的擴展方式, 自定義了一些Dubbo的標簽
<?xml version="1.0"encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" xsi:schemaLocation="http://www.springframework.org/schema/http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd"> <!--配置應(yīng)用名稱--> <dubbo:applicationname="dubbo1-consumer"/> <!--配置注冊中心地址--> <dubbo:registryaddress="zookeeper://localhost:2181"/> <!--掃描dubbo的注解--> <dubbo:annotationpackage="com.itheima.controller"/> <!--消費者配置> <dubbo:consumercheck="false"timeout="1000"retries="o"/> </beans>
為了降低我們此處的學(xué)習(xí)成本, 不在引入Dubbo第三方框架了, 以Spring的context命名空間去進行講解, 該方式也是命名空間擴展方式。 需求:加載外部properties文件, 將鍵值對存儲在Spring容器中
jdbc.url=jdbc:mysql://localhost:3306/db_shopping
jdbc.username=root
jdbc.password=1234
1.創(chuàng)建外部properties文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/bookshop
jdbc.username=root
jdbc.password=1234
2.通過命名空間引用外部文件
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" 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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd "> <!--加載properties文件--> <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
3.配置屬性
<!--配置數(shù)據(jù)源信息--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${jdbc.driver}"></property> <property name="url" value="${jdbc.url}"></property> <property name="username" value="${jdbc.username}"></property> <property name="password" value="${jdbc.password}"></property> </bean>
外部命名空間標簽的執(zhí)行流程,如下:
- 將自定義標簽的約束與物理約束文件與網(wǎng)絡(luò)約束名稱的約束以鍵值對形式存儲到一個spring.schemas文件里 , 該文件存儲在類加載路徑的META-INF里, Spring會自動加載到;
- 將自定義命名空間的名稱與自定義命名空間的處理器映射關(guān)系以鍵值對形式存在到一個叫spring.handlers文 件里, 該文件存儲在類加載路徑的META-INF里, Spring會自動加載到;
- 準備好NamespaceHandler, 如果命名空間只有一個標簽, 那么直接在parse方法中進行解析即可, 一般解析結(jié) 果就是注冊該標簽對應(yīng)的BeanDefinition。如果命名空間里有多個標簽, 那么可以在init方法中為每個標簽都注 冊一個BeanDefinitionParser, 在執(zhí)行NamespaceHandler的parse方法時在分流給不同的 BeanDefinitionParser進行解析(重寫doParse方法即可) 。
四、案例演示
設(shè)想自己是一名架構(gòu)師, 進行某一個框架與Spring的集成開發(fā), 效果是通過一個指示標簽, 向Spring容器中自動注入一個BeanPostProcessor
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/xmlSchema-instance" xmlns:haohao="http://www.tangyuan.com/haohao" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.tangyuan.com/haohao http://www.tangyuan.com/haohao/haohao-annotation.xsd"> <haohao:annotation-driven/> </beans>
步驟分析:
1.確定命名空間名稱、schema虛擬路徑、標簽名稱;
2.編寫schema約束文件haohao-annotation.xsd
3.在類加載路徑下創(chuàng)建META-INF目錄, 編寫約束映射文件spring.schemas和處理器映射文件spring.handlers
4.編寫命名空間處理器HaohaoNamespaceHandler, 在init方法中注冊HaohaoBeanDefinitionParser
5.編寫標簽的解析器HaohaoBeanDefinitionParser, 在parse方法中注冊HaohaoBeanPostProcessor
6.編寫HaohaoBeanPostProcessor
========以上五步是框架開發(fā)者寫的,以下是框架使用者寫的
1.在applicationContext.xml配置文件中引入命名空間
2.在applicationContext.xml配置文件中使用自定義的標簽
代碼演示:
1.確定命名空間名稱、schema虛擬路徑、標簽名稱;
2.編寫schema約束文件haohao-annotation.xsd
<?xml version="1.0" encoding="UTF-8"?> <xsd:schema xmlns="http://www.tangyuan.com/haohao" xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.tangyuan.com/haohao"> <xsd:element name="annotation-driven"></xsd:element> </xsd:schema>
3.在類加載路徑下創(chuàng)建META-INF目錄, 編寫約束映射文件spring.schemas和處理器映射文件spring.handlers
http\://www.tangyuan.com/haohao/haohao-annotation.xsd=com/tangyuan/haohao/config/haohao-annotation.xsd
http\://www.tangyuan.com/haohao=com.tangyuan.handlers.HaohaoNamespaceHandler
4.編寫命名空間處理器HaohaoNamespaceHandler, 在init方法中注冊HaohaoBeanDefinitionParser
package com.tangyuan.handlers; import org.springframework.beans.factory.xml.NamespaceHandlerSupport; public class HaohaoNamespaceHandler extends NamespaceHandlerSupport { @Override public void init() { //初始化,一般情況下,一個名空間下有多個標簽,會在init方法中為每一個標簽注冊一個標簽解析器 this.registerBeanDefinitionParser("annotation-driven",new HaohaoBeanDefinitionParser()); } }
5.編寫標簽的解析器HaohaoBeanDefinitionParser, 在parse方法中注冊HaohaoBeanPostProcessor
package com.tangyuan.handlers; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.RootBeanDefinition; import org.springframework.beans.factory.xml.BeanDefinitionParser; import org.springframework.beans.factory.xml.ParserContext; import org.w3c.dom.Element; public class HaohaoBeanDefinitionParser implements BeanDefinitionParser { @Override public BeanDefinition parse(Element element, ParserContext parserContext) { //注入一個BeanPostProcessor BeanDefinition beanDefinition = new RootBeanDefinition(); beanDefinition.setBeanClassName("com.tangyuan.processor.HaohaoBeanPostProcessor"); parserContext.getRegistry().registerBeanDefinition("haohaoBeanPostProessor",beanDefinition); return beanDefinition; } }
6.編寫HaohaoBeanPostProcessor
package com.tangyuan.processor; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; public class HaohaoBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("HaohaoBeanPostProcessor執(zhí)行...."); return bean; } }
7.在主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" xmlns:context="http://www.springframework.org/schema/context" xmlns:haohao="http://www.tangyuan.com/haohao" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo" 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/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd http://www.tangyuan.com/haohao http://www.tangyuan.com/haohao/haohao-annotation.xsd "> <!--使用自定義的命名空間標簽--> <haohao:annotation-driven></haohao:annotation-driven>
到此這篇關(guān)于Spring使用xml方式整合第三方框架流程詳解的文章就介紹到這了,更多相關(guān)Spring整合第三方框架內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java實現(xiàn)將導(dǎo)出帶格式的Excel數(shù)據(jù)到Word表格
在Word中制作報表時,我們經(jīng)常需要將Excel中的數(shù)據(jù)復(fù)制粘貼到Word中,這樣則可以直接在Word文檔中查看數(shù)據(jù)而無需打開另一個Excel文件。本文將通過Java應(yīng)用程序詳細介紹如何把帶格式的Excel數(shù)據(jù)導(dǎo)入Word表格。希望這篇文章能對大家有所幫助2022-11-11SpringCloud升級2020.0.x版之OpenFeign簡介與使用實現(xiàn)思路
在微服務(wù)系統(tǒng)中,我們經(jīng)常會進行 RPC 調(diào)用。在 Spring Cloud 體系中,RPC 調(diào)用一般就是 HTTP 協(xié)議的調(diào)用。對于每次調(diào)用,都要經(jīng)過一系列詳細步驟,接下來通過本文給大家介紹SpringCloud OpenFeign簡介與使用,感興趣的朋友一起看看吧2021-10-10mybatis中string和date的轉(zhuǎn)換方式
這篇文章主要介紹了mybatis中string和date的轉(zhuǎn)換方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-08-08java實現(xiàn)日歷(某年的日歷,某月的日歷)用戶完全自定義
本篇文章介紹了,java實現(xiàn)日歷(某年的日歷,某月的日歷)用戶完全自定義。需要的朋友參考下2013-05-05Spring多數(shù)據(jù)源導(dǎo)致配置失效的解決
這篇文章主要介紹了Spring多數(shù)據(jù)源導(dǎo)致配置失效的解決方案,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-01-01