标签: SpringBoot

  • SpringBoot2.1.1使用Zuul创建SpringCloud微服务Gateway网关

    1、在新的SpringBoot项目中的pom.xml引入如下依赖:

    		<!-- 引入Zuul starter -->
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-starter</artifactId>
    		</dependency>
    		<!-- 连接Eureka -->
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    		</dependency>

    2、在pom.xml的project中加入SpringCloud的版本管理配置:

    	<dependencyManagement>
    		<dependencies>
    			<dependency>
    				<groupId>org.springframework.cloud</groupId>
    				<artifactId>spring-cloud-dependencies</artifactId>
    				<version>${spring-cloud.version}</version>
    				<type>pom</type>
    				<scope>import</scope>
    			</dependency>
    		</dependencies>
    	</dependencyManagement>

    3、编辑配置文件application.propertites:

    spring.application.name = zero4j-zuul-gateway
    
    eureka.client.serviceUrl.defaultZone = http://admin:123456@localhost:8761/eureka/
    eureka.instance.instance-id = ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
    eureka.instance.prefer-ip-address = true
    
    #只要访问以/api/v1/areas开头的多层目录都可以路由到服务名为zero4j-provider-area的服务上.
    zuul.routes.zero4j-provider-area.path = /api/v1/areas
    zuul.routes.zero4j-provider-area.service-id = zero4j-provider-area
    zuul.routes.zero4j-provider-area.stripPrefix = false
    
    server.port = 4000

    4、最后在application启动类中加入@EnableDiscoveryClient和@EnableZuulProxy注解:

    package com.zero4j;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
    import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
    
    @EnableDiscoveryClient
    @EnableZuulProxy
    @SpringBootApplication
    public class Zero4jZuulGatewayApplication {
    
    	public static void main(String[] args) {
    		SpringApplication.run(Zero4jZuulGatewayApplication.class, args);
    	}
    
    }
    

     

  • SpringBoot2.1.1微服务架构引入SpringCloudSecurity安全认证

    1、在eureka服务器的pom.xml中引入依赖:

    	<!-- Spring Cloud Security 依赖 -->
    	<dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-security</artifactId>
            </dependency>

    2、创建密码安全认证密码匹配规则类MyPasswordEncoder.java:

    package com.zero4j.config;
    
    import org.springframework.security.crypto.password.PasswordEncoder;
    
    public class MyPasswordEncoder implements PasswordEncoder {
    
    	@Override
        public String encode(CharSequence charSequence) {
            return charSequence.toString();
        }
    
        @Override
        public boolean matches(CharSequence charSequence, String s) {
            return s.equals(charSequence.toString());
        }
        
    }
    

    3、在eureka服务器中创建配置类SecurityConfig.java:

    package com.zero4j.config;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
    import org.springframework.security.crypto.factory.PasswordEncoderFactories;
    import org.springframework.security.crypto.password.PasswordEncoder;
    import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
    import org.springframework.security.config.annotation.web.builders.HttpSecurity;
    import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
    import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
    
    @Configuration
    @EnableWebSecurity
    public class SecurityConfig extends WebSecurityConfigurerAdapter {
        
    	@Bean
        public PasswordEncoder passwordEncoder() {
            return PasswordEncoderFactories.createDelegatingPasswordEncoder();
        }
        
        //@Autowired
        //BCryptPasswordEncoder passwordEncoder;
    
        @Override
        protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        	
        	//以前可以不指定PasswordEncoder,但是新的SpringBoot依赖的SpringCloudScurity需要了
        	//auth.inMemoryAuthentication().withUser("admin").password("123456").roles("ADMIN");
        	//这样,密码以明文的方式进行匹配
        	auth.inMemoryAuthentication().passwordEncoder(new MyPasswordEncoder()).withUser("admin").password("123456").roles("ADMIN");
        	//auth.inMemoryAuthentication().withUser("admin").password(passwordEncoder.encode("123456")).roles("ADMIN");
        }
    
        @Override
        protected void configure(HttpSecurity http) throws Exception {
            http.csrf().ignoringAntMatchers("/eureka/**");
            super.configure(http);
        }
    }

    4、启动服务,访问eureka服务中心,使用admin:123456进行登录,成功进入eureka控制台

    5、对微服务提供者的application.propertites说引用的eureka服务中心地址的前面加入“admin:123456@”,如:http\://admin:123456@localhost\:8761/eureka/ ,然后启动即可~

  • SpringBoot2.1.1使用SpringCloud的Feign调用Eureka微服务并开启Hystrix熔断机制

    1、先在pom.xml中引入如下依赖:

    	<!--Netflix Eureka依赖-->
    	<dependency>
    		<groupId>org.springframework.cloud</groupId>
    		<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    	</dependency>
    	<dependency>
    		<groupId>org.springframework.cloud</groupId>
    		<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    	</dependency>
    	<!--springcloud整合的openFeign-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-openfeign</artifactId>
            </dependency>

    2、在pom.xml中的<project></project>之间增加以下关于springcloud的版本管理:

    	<dependencyManagement>
    		<dependencies>
    			<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-dependencies</artifactId>
    			<version>${spring-cloud.version}</version>
    			<type>pom</type>
    			<scope>import</scope>
    			</dependency>
    		</dependencies>
    	</dependencyManagement>

    3、在application.propertites中增加如下配置:

    #feign的配置,连接超时及读取超时配置
    feign.client.config.default.connectTimeout=5000
    feign.client.config.default.readTimeout=5000
    feign.client.config.default.loggerLevel=basic
    #开启熔断功能
    feign.hystrix.enabled=true

    4、在application启动入口增加@EnableFeignClients注解:

    @EnableFeignClients
    @ImportResource("classpath:hibernate.xml")
    @SpringBootApplication
    public class Zero4jApplication extends SpringBootServletInitializer{
    	
    	@Override
    	protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
    		return builder.sources(Zero4jApplication.class);
    	}
    
    	public static void main(String[] args) {
    		SpringApplication.run(Zero4jApplication.class, args);
    	}
    
    }

    5、创建FeignClient客户端:

    package com.zero4j.controller.api.v1;
    
    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.DeleteMapping;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PatchMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    
    @FeignClient(value="zero4j-provider-area", fallback=AreasApiHystrixV1.class)
    public interface AreasApiFeignClientV1 {
    
    	@PatchMapping(value="api/v1/areas/{id}")
    	String update(
    			@PathVariable(value="id") String id,
    			@RequestParam(value="token",required=false) String token,
    			@RequestParam(value="name",required=false) String name,
    			@RequestParam(value="parentId",required=false) String parentId,
    			@RequestParam(value="hasChildren",required=false) Boolean hasChildren
    		);
    
    }
    

    6、编写调用微服务的Controller:

    package com.zero4j.controller.api.v1;
    
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import net.sf.json.JSONObject;
    
    import org.hibernate.SessionFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.HttpEntity;
    import org.springframework.http.HttpHeaders;
    import org.springframework.http.HttpMethod;
    import org.springframework.http.MediaType;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.DeleteMapping;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.PatchMapping;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.PostMapping;
    import org.springframework.web.bind.annotation.RequestAttribute;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    import com.zero4j.model.area.service.AreaService;
    
    
    @RestController
    @RequestMapping("/api/v1/areas")
    public class AreasApiControllerV1 {
    
    	@Autowired
    	private AreaService areaService;
    	
    	@Autowired
    	private SessionFactory sessionFactory;
    	
    	@Autowired
    	private RestTemplate restTemplate;
    	
    	@PatchMapping(value="/{id}")
    	public ResponseEntity update(HttpServletRequest request,HttpServletResponse response,
    			@PathVariable(value="id") String id,
    			@RequestParam(required=false) String token,
    			@RequestParam(required=false) String name,
    			@RequestParam(required=false) String parentId,
    			@RequestParam(required=false) Boolean hasChildren
    		){
    		
    		return ResponseEntity.ok((String)areaApiFeignClient.update(id,token,name,parentId,hasChildren));
    	}
    	
    
    }
    

    7、编写熔断处理方法:

    package com.zero4j.controller.api.v1;
    
    import net.sf.json.JSONObject;
    
    import org.springframework.stereotype.Component;
    
    @Component
    public class AreasApiHystrixV1 implements AreasApiFeignClientV1 {
    
    	@Override
    	public String update(String id, String token, String name, String parentId, Boolean hasChildren) {
    		JSONObject out = new JSONObject();
    		out.put("status", 400);
    		out.put("message", "update服务异常");
    		out.put("debug", "update服务异常");
    		return out.toString();
    	}
    
    }
    

    8、启动服务,访问对应的api,分别在微服务开启、关闭的时候调用API,查看结果即可。

  • 使用SpringBoot2.1.1配置SpringCloudConfig服务

    配置中心服务器:

    1、在pom.xml中加入如下依赖:

    	        <dependency>
    	        	<groupId>org.springframework.boot</groupId>
    	        	<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>
    
    		<!-- Spring Cloud Config - Server依赖 -->
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-config-server</artifactId>
    			<version>2.1.1.RELEASE</version>
    		</dependency>

    注意高亮行,这个version需要和springboot的版本号一致。

    2、在启动类中加入@EnableConfigServer注解

    3、创建bootstrap.yml配置文件,本地配置如下:

    #服务启动端口配置:
    server:  
      port: 3000
      
    #指定配置文件所在目录或地址
    spring:
      profiles:
        active: native
      cloud:
        config:
          server:
            native:
              search-locations: classpath:/config/
              #search-locations: D:/Workspaces/zero4j/config/src/main/resources/config

    4、在项目的resources(class)目录中创建config文件夹,并在里面新增application-dev.properties文件,内容如下:

    server.address=127.0.0.1
    server.port=8081
    a.url=dev1233

    5、启动并访问 http://localhost:3000/application-dev.properties,能看到

    配置客户端:

    1、在pom.xml中加入如下依赖:

    		<dependency>
                		<groupId>org.springframework.boot</groupId>
                		<artifactId>spring-boot-starter-web</artifactId>
            	</dependency>
    
    		<!-- Spring Cloud Config - Client依赖 -->
    		<dependency>
    			<groupId>org.springframework.cloud</groupId>
    			<artifactId>spring-cloud-config-client</artifactId>
    			<version>2.1.1.RELEASE</version>
    		</dependency>

    同样的,version那里切记要跟springboot的版本一致。

    2、创建bootstrap.yml配置文件,配置如下:

    #启动端口配置:
    server:  
      port: 8080
    
    # 指明配置服务中心的网址
    spring:
      application:
        name: application
      cloud:
        config:
          label: master
          profile: dev
          uri: http://127.0.0.1:3000

    3、创建测试用的controller

    package com.zero4j.controller;
    
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    public class TestController {
    
    	@Value("${a.url}")
    	private String datUrl;
    	
    	@GetMapping(value = "/test")
    	public String hi(){
    		return datUrl;
    	}
    
    }
    

    4、启动并访问http://localhost:8081/test,便能看到client获取server的class中config里的配置文件对应的a.url配置

  • springboot2.1.1+hibernate5.0.12开启数据库二级缓存

    首先加入依赖到pom.xml:

    		<!-- hibernnate对二级缓存的支持 -->
    		<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-ehcache -->
    		<dependency>
    		    <groupId>org.hibernate</groupId>
    		    <artifactId>hibernate-ehcache</artifactId>
    		    <version>5.0.12.Final</version>
    		</dependency>
    		<!-- https://mvnrepository.com/artifact/net.sf.ehcache/ehcache -->
    		<dependency>
    		    <groupId>net.sf.ehcache</groupId>
    		    <artifactId>ehcache</artifactId>
    		    <version>2.10.6</version>
    		</dependency>
    

    然后在hibernate.xml配置文件中加入以下参数:

    				<!-- hibernate5的二级缓存配置 -->
    				<prop key="hibernate.cache.use_second_level_cache">true</prop>
    				<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>

    接着创建二级缓存配置文件ehcache.xml:

    <?xml version="1.0" encoding="UTF-8"?>
    <ehcache>
        <diskStore path="java.io.tmpdir"/>
        <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            overflowToDisk="true"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            diskPersistent="false"/>
    </ehcache>

    最后在需要开启缓存的pojo类中加入注解cache注解:

    @Entity
    @GenericGenerator(name="idGenerator", strategy="uuid")
    @Cache(usage=CacheConcurrencyStrategy.READ_WRITE)
    public class Area {
    
    	/**
    	 * id:UUID生成法则
    	 */
    	@Id
    	@GeneratedValue(generator="idGenerator")
    	private String id;

    配置完毕,启动项目,输出hibernate的sql执行语句,会发现第二次查询相同对象时不再执行查询语句。

  • 创建一个基于SpringBoot2.1.x的JavaFX程序

    1.创建SpringBoot项目

    到 https://start.spring.io/ 创建一个SpringBoot2.1.x项目,解压后使用MyEclipse2015导入为maven项目~

    2.引入JavaFX

    对SpringBoot入口程序Application进行改造,继承javafx的application类,并引入接口CommandLineRunner, Consumer<Stage>,接着加入如下代码(高亮部分):

    package com.dgzq;
    
    import java.util.function.Consumer;
    
    import javafx.application.Application;
    import javafx.application.Platform;
    import javafx.scene.Scene;
    import javafx.scene.control.Tab;
    import javafx.scene.control.TabPane;
    import javafx.scene.control.TabPane.TabClosingPolicy;
    import javafx.stage.Stage;
    
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class DgzqApplication extends Application implements CommandLineRunner, Consumer<Stage>{
    
    	public static void main(String[] args) {
    		SpringApplication.run(DgzqApplication.class, args);
    	}
    	
    	@Override
    	public void run(String... args) throws Exception {
    		
    		Platform.runLater(new Runnable() {
    		    @Override
    		    public void run() {
    		    	
    		    	Stage stage = new Stage();
            		
    		    	try {
    					start(stage);
    				} catch (Exception e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
            		
    		    }
    		});
    		
    	}
    
    	@Override
    	public void start(Stage primaryStage) throws Exception {
    		accept(primaryStage);
    	}
    
    	@Override
    	public void accept(Stage stage) {
    		
    		TabPane tabPane = new TabPane();	//增加标签面板
    		tabPane.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE);
    		
    		Scene scene = new Scene(tabPane, 900, 690);
    		stage.setScene(scene);
    		stage.setTitle("测试界面");
    		
    		Tab tab1 = new Tab("标签页1");
    		Tab tab2 = new Tab("标签页2");
    		tabPane.getTabs().addAll(tab1,tab2);
    		tabPane.getSelectionModel().select(tab1);	//设置默认选中
    		
    		stage.show();
    	}
    
    }
    

    然后启动,出现如下界面则为成功:

    ac571e727fe9d73b3500c54a3e2117c

     

    3.增加预加载页面

    在pom.xml加入如下依赖:

    		<!-- SpringBoot2.x与JavaFX的集成 -->
    		<!-- https://mvnrepository.com/artifact/de.roskenet/springboot-javafx-support -->
    		<dependency>
    		    <groupId>de.roskenet</groupId>
    		    <artifactId>springboot-javafx-support</artifactId>
    		    <version>2.1.6</version>
    		</dependency>

     

    新增一个启动入口文件如MainApplication.java用于展示欢迎界面,代码如下:

    package com.dgzq;
    
    import java.io.File;
    
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    import de.felixroske.jfxsupport.AbstractJavaFxApplicationSupport;
    import de.felixroske.jfxsupport.SplashScreen;
    import javafx.scene.Scene;
    import javafx.scene.control.Alert;
    import javafx.stage.Stage;
    import javafx.stage.StageStyle;
    import javafx.scene.paint.Color;
    
    @SpringBootApplication
    public class MainApplication extends AbstractJavaFxApplicationSupport {
    	
    	public static SplashScreen splashScreen;
    	public static Stage splashStage;
    	public static Scene splashScene;
    	
        public static void main(String[] args) {
        	
        	//启动(若需要以fxml形式展示主界面,则第二个传参可以为"MainStageView.class"之类的)
        	launch(MainApplication.class, null, args);
            
        }
    
        @Override
        public void start(Stage stage) throws Exception {
    
        	MainApplication.splashScreen = new SplashScreen();
        	MainApplication.splashStage = new Stage(StageStyle.TRANSPARENT);
        	MainApplication.splashScene = new Scene(splashScreen.getParent(), Color.TRANSPARENT);
        	MainApplication.splashStage.setScene(splashScene);
        	MainApplication.splashStage.initStyle(StageStyle.TRANSPARENT);
        	MainApplication.splashStage.show();
    
        }
        
    }

    在预加载完成后还要再正式界面中隐藏掉本界面,因此要在原来的application类的stage.show()前面加入如下代码:

    MainApplication.splashStage.hide();
    MainApplication.splashStage.setScene(null);

    然后注释掉原来的application启动类中的main方法:

    /*public static void main(String[] args) {
    	SpringApplication.run(DgzqApplication.class, args);
    }*/

    最后启动刚刚新建的MainApplication.java,便会出现中间界面:

    d294a0cca4b571832aaa7b9c70f8363

    好了,大功告成。如果还需要引入sqlite数据库,则可以继续往下操作。

    4.引入hibernate并使用sqlite数据库

    在MainApplication中的 下方加入如下代码,以提示sqlite是否存在:

        	File databaseFile = new File("sqlite3.db");
        	if(!databaseFile.exists()){
    	    	Alert alert = new Alert(Alert.AlertType.INFORMATION);
    			alert.setTitle("错误");
    			alert.setHeaderText(null);
    			alert.setContentText("找不到数据库文件:sqlite3.db(本次运行将自动创建全新的空白数据库)");
    			alert.showAndWait();
        	}

    再pom.xml中加入如下依赖:

    	<!-- sqlite3驱动包 -->
            <!-- https://mvnrepository.com/artifact/org.xerial/sqlite-jdbc -->
    		<dependency>
    		    <groupId>org.xerial</groupId>
    		    <artifactId>sqlite-jdbc</artifactId>
    		    <version>3.28.0</version>
    		</dependency>
    		
    		<!-- SpringBoot与hibernate的集成配置 -->
    		<dependency>
    		    <groupId>org.springframework.boot</groupId>
    		    <artifactId>spring-boot-starter-data-jpa</artifactId>
    		</dependency>
    		<!-- SpringBoot使用Hibernate的SessionFactory -->
    		<dependency>
    		    <groupId>org.hibernate</groupId>
    		    <artifactId>hibernate-core</artifactId>
    		    <version>5.0.12.Final</version>
    		</dependency>
    		<dependency>
    		    <groupId>org.hibernate</groupId>
    		    <artifactId>hibernate-entitymanager</artifactId>
    		    <version>5.0.12.Final</version>
    		</dependency>
    		
    		<!-- SpringBoot2.x与JavaFX的集成 -->
    		<!-- https://mvnrepository.com/artifact/de.roskenet/springboot-javafx-support -->
    		<dependency>
    		    <groupId>de.roskenet</groupId>
    		    <artifactId>springboot-javafx-support</artifactId>
    		    <version>2.1.6</version>
    		</dependency>

     

    对原来的Application进行修改(加入高亮部分):

    package com.dgzq;
    
    import java.util.function.Consumer;
    
    import javafx.application.Application;
    import javafx.application.Platform;
    import javafx.scene.Scene;
    import javafx.scene.control.Tab;
    import javafx.scene.control.TabPane;
    import javafx.scene.control.TabPane.TabClosingPolicy;
    import javafx.stage.Stage;
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.CommandLineRunner;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.context.annotation.Bean;
    import org.springframework.orm.jpa.vendor.HibernateJpaSessionFactoryBean;
    
    @SpringBootApplication
    public class DgzqApplication extends Application implements CommandLineRunner, Consumer<Stage>{
    	
    	public static SessionFactory sessionFactory;
    	@Autowired
    	public void setSessionFactory(SessionFactory sessionFactory) {
    		DgzqApplication.sessionFactory = sessionFactory;
    	}
    	
    	@Bean
        public HibernateJpaSessionFactoryBean sessionFactory() {
            return new HibernateJpaSessionFactoryBean();
        }
    
    	/*public static void main(String[] args) {
    		SpringApplication.run(DgzqApplication.class, args);
    	}*/
    	
    	@Override
    	public void run(String... args) throws Exception {
    		
    		Platform.runLater(new Runnable() {
    		    @Override
    		    public void run() {
    		    	
    		    	Stage stage = new Stage();
            		
    		    	try {
    					start(stage);
    				} catch (Exception e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
            		
    		    }
    		});
    		
    	}
    
    	@Override
    	public void start(Stage primaryStage) throws Exception {
    		accept(primaryStage);
    	}
    
    	@Override
    	public void accept(Stage stage) {
    		
    		System.out.println("MainJavaFxApplication被实例化了");
    		System.out.println("MainJavaFxApplication.sessionFactory = "+sessionFactory);
    		
    		TabPane tabPane = new TabPane();	//增加标签面板
    		tabPane.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE);
    		
    		Scene scene = new Scene(tabPane, 900, 690);
    		stage.setScene(scene);
    		stage.setTitle("测试界面");
    		
    		Tab tab1 = new Tab("标签页1");
    		Tab tab2 = new Tab("标签页2");
    		tabPane.getTabs().addAll(tab1,tab2);
    		tabPane.getSelectionModel().select(tab1);	//设置默认选中
    		
    		MainApplication.splashStage.hide();
    		MainApplication.splashStage.setScene(null);
    		
    		stage.show();
    	}
    
    }
    

    增加sqlite的方言类SQLiteDialect.java:

    package com.fenji;
    
    import java.sql.Types;
    
    import org.hibernate.dialect.Dialect;
    import org.hibernate.dialect.function.StandardSQLFunction;
    import org.hibernate.dialect.function.SQLFunctionTemplate;
    import org.hibernate.dialect.function.VarArgsSQLFunction;
    import org.hibernate.type.StandardBasicTypes;
    
    public class SQLiteDialect extends Dialect {
        public SQLiteDialect() {
            super();
            registerColumnType(Types.BIT, "integer");
            registerColumnType(Types.TINYINT, "tinyint");
            registerColumnType(Types.SMALLINT, "smallint");
            registerColumnType(Types.INTEGER, "integer");
            registerColumnType(Types.BIGINT, "bigint");
            registerColumnType(Types.FLOAT, "float");
            registerColumnType(Types.REAL, "real");
            registerColumnType(Types.DOUBLE, "double");
            registerColumnType(Types.NUMERIC, "numeric");
            registerColumnType(Types.DECIMAL, "decimal");
            registerColumnType(Types.CHAR, "char");
            registerColumnType(Types.VARCHAR, "varchar");
            registerColumnType(Types.LONGVARCHAR, "longvarchar");
            registerColumnType(Types.DATE, "date");
            registerColumnType(Types.TIME, "time");
            registerColumnType(Types.TIMESTAMP, "timestamp");
            registerColumnType(Types.BINARY, "blob");
            registerColumnType(Types.VARBINARY, "blob");
            registerColumnType(Types.LONGVARBINARY, "blob");
            // registerColumnType(Types.NULL, "null");
            registerColumnType(Types.BLOB, "blob");
            registerColumnType(Types.CLOB, "clob");
            registerColumnType(Types.BOOLEAN, "integer");
    
            registerFunction("concat", new VarArgsSQLFunction(StandardBasicTypes.STRING, "", "||", ""));
            registerFunction("mod", new SQLFunctionTemplate(StandardBasicTypes.INTEGER, "?1 % ?2"));
            registerFunction("substr", new StandardSQLFunction("substr", StandardBasicTypes.STRING));
            registerFunction("substring", new StandardSQLFunction("substr", StandardBasicTypes.STRING));
        }
    
        public boolean supportsIdentityColumns() {
            return true;
        }
    
        public boolean hasDataTypeInIdentityColumn() {
            return false;
        }
    
        public String getIdentityColumnString() {
            return "integer";
        }
    
        public String getIdentitySelectString() {
            return "select last_insert_rowid()";
        }
    
        public boolean supportsLimit() {
            return true;
        }
    
        public String getLimitString(String query, boolean hasOffset) {
            return new StringBuffer(query.length() + 20).append(query).append(hasOffset ? " limit ? offset ?" : " limit ?")
                    .toString();
        }
    
        public boolean supportsTemporaryTables() {
            return true;
        }
    
        public String getCreateTemporaryTableString() {
            return "create temporary table if not exists";
        }
    
        public boolean dropTemporaryTableAfterUse() {
            return false;
        }
    
        public boolean supportsCurrentTimestampSelection() {
            return true;
        }
    
        public boolean isCurrentTimestampSelectStringCallable() {
            return false;
        }
    
        public String getCurrentTimestampSelectString() {
            return "select current_timestamp";
        }
    
        public boolean supportsUnionAll() {
            return true;
        }
    
        public boolean hasAlterTable() {
            return false;
        }
    
        public boolean dropConstraints() {
            return false;
        }
    
        public String getAddColumnString() {
            return "add column";
        }
    
        public String getForUpdateString() {
            return "";
        }
    
        public boolean supportsOuterJoinForUpdate() {
            return false;
        }
    
        public String getDropForeignKeyString() {
            throw new UnsupportedOperationException("No drop foreign key syntax supported by SQLiteDialect");
        }
    
        public String getAddForeignKeyConstraintString(String constraintName, String[] foreignKey, String referencedTable,
                String[] primaryKey, boolean referencesPrimaryKey) {
            throw new UnsupportedOperationException("No add foreign key syntax supported by SQLiteDialect");
        }
    
        public String getAddPrimaryKeyConstraintString(String constraintName) {
            throw new UnsupportedOperationException("No add primary key syntax supported by SQLiteDialect");
        }
    
        public boolean supportsIfExistsBeforeTableName() {
            return true;
        }
    
        public boolean supportsCascadeDelete() {
            return false;
        }
    
        @Override
        public boolean bindLimitParametersInReverseOrder() {
            return true;
        }
    }

    增加配置文件application.properties用于配置数据库(注意高亮行,要指向刚刚创建的方言类SQLiteDialect.java):

    spring.datasource.driver-class-name=org.sqlite.JDBC
    spring.datasource.url=jdbc:sqlite:sqlite3.db
    
    # Specify the DBMS
    #spring.jpa.database=SQLite
    # Show or not log for each sql query
    spring.jpa.show-sql=true
    # Hibernate ddl auto (create, create-drop, update)
    spring.jpa.hibernate.ddl-auto=update
    # Naming strategy
    spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy
    # stripped before adding them to the entity manager
    #spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
    spring.jpa.properties.hibernate.dialect=com.dgzq.SQLiteDialect
    # table column upcase problem
    spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
    spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
    # auto inject sessionFactory bean
    spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext

    好了,运行MainApplication看看效果:

    639fccfb32a10d16ee5a29089e0094f

    如图所示,输入sessionFactory不为空,则注入成功,后面大家自由发挥吧!

    5.补充:记得指定maven打包时的启动入口

    在pom.xml中加入如下高亮代码

    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.springframework.boot</groupId>
    				<artifactId>spring-boot-maven-plugin</artifactId>
    				<configuration>
    					<mainClass>com.dgzq.MainApplication</mainClass>
    				</configuration>
    			</plugin>
    		</plugins>
    	</build>

    大功告成!

  • SpringBoot配置文件spring.main.allow-bean-definition-overriding=true没生效的解决方法

    操作继承了“EnvironmentPostProcessor”的类,

    直接在java代码中 操作SpringApplication的属性,如下:

    application.setAllowBeanDefinitionOverriding(true);

     

  • 当在SpringBoot使用Redis的Session共享功能时,@EnableScheduling始终生效的问题。

    我在调试项目的redis共享时,遇到了这种情况:

    当我需要使用Redis来管理SpringBoot的Session时,会加入如下依赖:

    		<dependency>
    			<groupId>org.springframework.session</groupId>
    			<artifactId>spring-session-data-redis</artifactId>
    		</dependency>

    这个依赖会让启动类中的@EnableScheduling设定无效,就是说,此时无论有没有@EnableScheduling,系统中的所有定时器均会生效。

    唉~具体原因,我猜是因为这个功能需要用到定时器,所以会默认开启了呗~折腾了我半天,真浪费时间~

  • SpringBoot2.1.1整合hibernate5.0.12使用SessionFactory

    1、在pom.xml中加入如下依赖:

    		<!-- Spring的aspect切面支持 -->
    		<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
    		<dependency>
    		    <groupId>org.springframework</groupId>
    		    <artifactId>spring-aspects</artifactId>
    		    <version>4.2.5.RELEASE</version>
    		</dependency>
    
    		<!-- Spring的ORM(Hibernate)映射支持 -->
    		<!-- https://mvnrepository.com/artifact/org.springframework/spring-orm -->
    		<dependency>
    		    <groupId>org.springframework</groupId>
    		    <artifactId>spring-orm</artifactId>
    		    <!-- <version>5.0.12.RELEASE</version>
    		    <version>4.3.11.RELEASE</version> -->
    		    <version>4.2.5.RELEASE</version>
    		</dependency>
    
    		<!-- Spring对Hibernate-SessionFactory的事务管理支持 -->
    		<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
    		<dependency>
    		    <groupId>org.hibernate</groupId>
    		    <artifactId>hibernate-core</artifactId>
    		    <version>5.0.12.Final</version>
    		</dependency>
    
    		<!-- mysql连接驱动 -->    
    		<dependency>    
    			<groupId>mysql</groupId>    
    			<artifactId>mysql-connector-java</artifactId>    
    			<version>5.1.9</version>
    		</dependency>

    如果pom.xml中有如下jpa依赖,记得清注释以下内容:

    		<!-- SpringBoot对JPA的支持 -->
    		<!-- <dependency>
    		    <groupId>org.springframework.boot</groupId>
    		    <artifactId>spring-boot-starter-data-jpa</artifactId>
    		</dependency> -->

    如果出现FilterRegistrationBean报错,则意味着缺少SpringMVC的filter依赖,办法之一是引入含有该filter的依赖(eureka的server依赖也是包含的):

    		<!-- SpringMVC的配置 -->
    		<dependency>
    			<groupId>org.springframework.boot</groupId>
    	        	<artifactId>spring-boot-starter-web</artifactId>
    		</dependency>

     

    2、在application.properties中加入如下配置:

    #mysql
    spring.datasource.url=jdbc\:mysql\://localhost\:3306/xxxxx?useSSL\=false&characterEncoding\=utf8
    spring.datasource.username=root
    spring.datasource.password=
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver

    如果在低版本SpringBoot中进行配置,则可能会遇到错误“Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true”,此时则需要在application.properties补充配置:

    spring.main.allow-bean-definition-overriding=true

    因为SpringBoot的SessionFactory会自动注入默认的Transactional事务管理器,但这个事务管理器搭配hibernate的SessionFactory会出现数据库连接池线程卡死的问题,即假如配置线程池的连接数为10,一旦连接数大于10,则线程池会出现卡死的情况,因此我们需要自行配置hibernate的事务管理器来覆盖SpringBoot原有的Transactional事务管理器。

    3、在SpringBoot的启动入口类上加入注解@ImportResource(“classpath:hibernate.xml”):

    @SpringBootApplication
    @ImportResource("classpath:hibernate.xml")
    public class xxxxxApplication extends SpringBootServletInitializer{
    
    	public static void main(String[] args) {
    		SpringApplication.run(xxxxxApplication.class, args);
    	}
    
    }

    4、在resources目录中加入配置文件hibernate.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:jee="http://www.springframework.org/schema/jee"
    	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
    	xmlns:p="http://www.springframework.org/schema/p" xmlns:util="http://www.springframework.org/schema/util"
    	xmlns:tool="http://www.springframework.org/schema/tool" xmlns:context="http://www.springframework.org/schema/context"
    	xsi:schemaLocation="http://www.springframework.org/schema/beans
               http://www.springframework.org/schema/beans/spring-beans.xsd
               http://www.springframework.org/schema/tx
               http://www.springframework.org/schema/tx/spring-tx.xsd
               http://www.springframework.org/schema/aop
               http://www.springframework.org/schema/aop/spring-aop.xsd
               http://www.springframework.org/schema/jee
               http://www.springframework.org/schema/jee/spring-jee.xsd
               http://www.springframework.org/schema/context
               http://www.springframework.org/schema/context/spring-context.xsd
               http://www.springframework.org/schema/util
               http://www.springframework.org/schema/util/spring-util.xsd
               http://www.springframework.org/schema/tool
               http://www.springframework.org/schema/tool/spring-tool.xsd"
        default-autowire="no">
    	
    	<!-- hibernate sessionFactory 创建 -->
    	<!-- hibernate.cfg.xml Spring config -->
    	<bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
    		<!-- connection -->
    		<property name="dataSource">
    			<ref bean="dataSource" />
    		</property>
    		<!-- hibernate 类文件配置 -->
    		<!-- hibernate自身属性 -->
    		<property name="hibernateProperties">
    			<props>
    				<!-- 显示Hibernate 持久化操作所生成的SQL -->
    				<prop key="hibernate.show_sql">false</prop>
    				<!-- 将SQL脚本进行格式化后在输出 -->
    				<prop key="hibernate.format_sql">true</prop>
    				<!-- 指定数据库方言 -->
    				<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
    				<!-- **************** -->
    				<prop key="hibernate.hbm2ddl.auto">update</prop>
    				<!-- 解决no session found -->
    				<!-- <prop key="hibernate.current_session_context_class">thread</prop> -->
    				
    				<!-- <prop key="hibernate.cache.use_second_level_cache">true</prop> -->
    				<!-- hibernate4的二级缓存配置 -->
    				<!-- <prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop> -->
    				<!-- hibernate3的二级缓存配置 -->
    				<!-- <prop name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop> -->
            		<!-- 开启查询缓存 -->
    				<!-- <prop key="hibernate.cache.use_query_cache">true</prop> -->
    				
    			</props>
    		</property>
    		<!-- 自动扫描注解方式配置的hibernate类文件 -->
    		<property name="packagesToScan">
    			<list>
    				<value>com.zero4j.model</value>
    			</list>
    		</property>
    		<!-- 手动加载配置映射文件 -->
    		<property name="mappingResources">
    			<list>
    				<!-- <value>com/***/model/order/Order.hbm.xml</value> -->
    			</list>
    		</property>
    		<!-- 手动加载注解类映射文件-->
    		<!-- <property name="annotatedClasses">
    			<list>
    				<value>com.zero4j.model.test.Test</value>
    			</list>
    		</property> -->
    	</bean>
    
    	<!-- 开启注解事务 只对当前配置文件有效 -->
      	<tx:annotation-driven transaction-manager="txManager"/>
    	<bean id="txManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager">
            	<property name="sessionFactory" ref="sessionFactory"/>
       	</bean>
    
    </beans>
    

    5、增加事务管理配置,有两种方式,一种是使用SpringBoot的config注入方式,另外一种是加在hibernate.xml中。(记住下面5.1和5.2是二选一)

    5.1、使用SpringBoot的confiug注入方式:增加配置文件TransactionAdviceConfig.java:

    package com.isuidian.config;
    
    
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.aop.Advisor;
    import org.springframework.aop.aspectj.AspectJExpressionPointcut;
    import org.springframework.aop.support.DefaultPointcutAdvisor;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.transaction.PlatformTransactionManager;
    import org.springframework.transaction.TransactionDefinition;
    import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
    import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
    import org.springframework.transaction.interceptor.TransactionInterceptor;
    
    @Aspect
    @Configuration
    public class TransactionAdviceConfig {
    
    	 //使dao使用session
    	private static final String AOP_POINTCUT_EXPRESSION = " (execution(* com..dao..*.*(..))) ";
    	//controller由过滤器中进行设置,这里设置会抽风
    	/*private static final String AOP_POINTCUT_EXPRESSION2 = " (execution(* com..controller..*.*(..))) ";*/
    	 
    	 
        @Autowired
        private PlatformTransactionManager transactionManager;
    
        @Bean
        public TransactionInterceptor txAdvice() {
    
            DefaultTransactionAttribute txAttr_REQUIRED = new DefaultTransactionAttribute();
            txAttr_REQUIRED.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
    
            DefaultTransactionAttribute txAttr_REQUIRED_READONLY = new DefaultTransactionAttribute();
            txAttr_REQUIRED_READONLY.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
            txAttr_REQUIRED_READONLY.setReadOnly(true);
            
            
            DefaultTransactionAttribute txAttr_READONLY = new DefaultTransactionAttribute();
            txAttr_READONLY.setReadOnly(true);
            
            
    
            NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
    
            source.addTransactionalMethod("save*", txAttr_REQUIRED);
            source.addTransactionalMethod("add*", txAttr_REQUIRED);
            source.addTransactionalMethod("create*", txAttr_REQUIRED);
            source.addTransactionalMethod("insert*", txAttr_REQUIRED);
            source.addTransactionalMethod("update*", txAttr_REQUIRED);
            source.addTransactionalMethod("merge*", txAttr_REQUIRED);
            source.addTransactionalMethod("del*", txAttr_REQUIRED);
            source.addTransactionalMethod("remove*", txAttr_REQUIRED);
            source.addTransactionalMethod("put*", txAttr_REQUIRED);
            source.addTransactionalMethod("use*", txAttr_REQUIRED);
            source.addTransactionalMethod("exec*", txAttr_REQUIRED);
            source.addTransactionalMethod("set*", txAttr_REQUIRED);
            
            
            source.addTransactionalMethod("get*", txAttr_REQUIRED_READONLY);//特殊,service在save后会重新读取,如果设置成REQUIRED_READONLY,则save不会保存数据
            source.addTransactionalMethod("count*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("find*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("list*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("query*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("find*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("is*", txAttr_REQUIRED_READONLY);
            
            /*
            source.addTransactionalMethod("save*", txAttr_REQUIRED);
            source.addTransactionalMethod("delete*", txAttr_REQUIRED);
            source.addTransactionalMethod("update*", txAttr_REQUIRED);
            source.addTransactionalMethod("exec*", txAttr_REQUIRED);
            source.addTransactionalMethod("set*", txAttr_REQUIRED);
            source.addTransactionalMethod("get*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("query*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("find*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("list*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("count*", txAttr_REQUIRED_READONLY);
            source.addTransactionalMethod("is*", txAttr_REQUIRED_READONLY);
            
            */
            source.addTransactionalMethod("*", txAttr_READONLY);
            return new TransactionInterceptor(transactionManager, source);
        }
    
        @Bean
        public Advisor txAdviceAdvisor() {
            AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
            pointcut.setExpression( AOP_POINTCUT_EXPRESSION );
            return new DefaultPointcutAdvisor(pointcut, txAdvice());
        }
        
       /* @Bean
        public Advisor txAdviceAdvisor2() {
            AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
            pointcut.setExpression( AOP_POINTCUT_EXPRESSION2 );
            return new DefaultPointcutAdvisor(pointcut, txAdvice());
        }*/
    }

    5.2、加在hibernate.xml中:

        <tx:advice id="txAdvice" transaction-manager="txManager">
            <tx:attributes>
                <tx:method name="save*" propagation="REQUIRED" />
                <tx:method name="add*" propagation="REQUIRED" />
                <tx:method name="create*" propagation="REQUIRED" />
                <tx:method name="insert*" propagation="REQUIRED" />
                <tx:method name="update*" propagation="REQUIRED" />
                <tx:method name="merge*" propagation="REQUIRED" />
                <tx:method name="del*" propagation="REQUIRED" />
                <tx:method name="remove*" propagation="REQUIRED" />
                <tx:method name="put*" propagation="REQUIRED" />
                <tx:method name="use*" propagation="REQUIRED"/>
                <!--hibernate4必须配置为开启事务 否则 getCurrentSession()获取不到-->
                <tx:method name="get*" propagation="REQUIRED" read-only="true" />
                <tx:method name="count*" propagation="REQUIRED" read-only="true" />
                <tx:method name="find*" propagation="REQUIRED" read-only="true" />
                <tx:method name="list*" propagation="REQUIRED" read-only="true" />
                <tx:method name="*" read-only="true" />
            </tx:attributes>
        </tx:advice>

     

    6、增加事务管理过滤器FilterConfig.java,自动开启事务管理:

    package com.isuidian.config;
    
    
    import org.aspectj.lang.annotation.Aspect;
    import org.springframework.boot.web.servlet.FilterRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.orm.hibernate5.support.OpenSessionInViewFilter;
    
    @Aspect
    @Configuration
    public class FilterConfig {
    
    	//解决调用接口时session抽风的问题
    	@Bean
    	public FilterRegistrationBean<OpenSessionInViewFilter> testFilterRegistration() {	
    		FilterRegistrationBean<OpenSessionInViewFilter> registration = new FilterRegistrationBean<>();
    		registration.setFilter(new OpenSessionInViewFilter());
    		registration.addUrlPatterns("/*");//配置过滤路径
    		return registration;
    	}
    	
    }

    7、搞掂,启动项目!在需要使用SessionFactory的地方使用如下方式注入即可:

    @Autowired
    private SessionFactory sessionFactory;

     

    常见问题

    重复的依赖错误

    错误提示如下:

    org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unsatisfied dependency expressed through method 'entityManagerFactory' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'entityManagerFactoryBuilder' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unsatisfied dependency expressed through method 'entityManagerFactoryBuilder' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaVendorAdapter' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.JpaVendorAdapter]: Factory method 'jpaVendorAdapter' threw exception; nested exception is java.lang.NoSuchFieldError: HANA
    	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:769) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:509) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1288) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1083) ~[spring-context-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:853) ~[spring-context-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546) ~[spring-context-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142) ~[spring-boot-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) [spring-boot-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) [spring-boot-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) [spring-boot-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at com.gushing.GushingApplication.main(GushingApplication.java:29) [classes/:na]
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201]
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201]
    	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201]
    	at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:49) [spring-boot-devtools-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'entityManagerFactoryBuilder' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Unsatisfied dependency expressed through method 'entityManagerFactoryBuilder' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaVendorAdapter' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.JpaVendorAdapter]: Factory method 'jpaVendorAdapter' threw exception; nested exception is java.lang.NoSuchFieldError: HANA
    	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:769) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:509) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1288) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:273) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1237) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1164) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:857) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:760) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	... 24 common frames omitted
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'jpaVendorAdapter' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.JpaVendorAdapter]: Factory method 'jpaVendorAdapter' threw exception; nested exception is java.lang.NoSuchFieldError: HANA
    	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:627) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:456) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1288) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:273) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1237) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1164) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:857) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:760) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	... 38 common frames omitted
    Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.orm.jpa.JpaVendorAdapter]: Factory method 'jpaVendorAdapter' threw exception; nested exception is java.lang.NoSuchFieldError: HANA
    	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:622) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	... 52 common frames omitted
    Caused by: java.lang.NoSuchFieldError: HANA
    	at org.springframework.boot.autoconfigure.orm.jpa.DatabaseLookup.<clinit>(DatabaseLookup.java:56) ~[spring-boot-autoconfigure-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.boot.autoconfigure.orm.jpa.JpaProperties.determineDatabase(JpaProperties.java:142) ~[spring-boot-autoconfigure-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.boot.autoconfigure.orm.jpa.JpaBaseConfiguration.jpaVendorAdapter(JpaBaseConfiguration.java:112) ~[spring-boot-autoconfigure-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration$$EnhancerBySpringCGLIB$$f91d7855.CGLIB$jpaVendorAdapter$4(<generated>) ~[spring-boot-autoconfigure-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration$$EnhancerBySpringCGLIB$$f91d7855$$FastClassBySpringCGLIB$$292a616.invoke(<generated>) ~[spring-boot-autoconfigure-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:244) ~[spring-core-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:363) ~[spring-context-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	at org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaConfiguration$$EnhancerBySpringCGLIB$$f91d7855.jpaVendorAdapter(<generated>) ~[spring-boot-autoconfigure-2.1.1.RELEASE.jar:2.1.1.RELEASE]
    	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_201]
    	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_201]
    	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_201]
    	at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_201]
    	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154) ~[spring-beans-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    	... 53 common frames omitted
    
    

    这很有可能你的依赖中有重复的内容,如:

    		<dependency>
    			<groupId>org.hibernate</groupId>
    			<artifactId>hibernate-entitymanager</artifactId>
    			<version>${hibernate.version}</version>
    		</dependency>

    这个是需要注释掉的,不然会报错。

  • 在SpringBoot中使用SessionFactory的方法

    首先项目中已经使用JPA的方式连接,然后加入hibernate依赖:

    	<properties>
    		<java.version>1.8</java.version>
    		<hibernate.version>5.0.12.Final</hibernate.version>
    	</properties>
    		<!-- SpringBoot使用Hibernate的SessionFactory -->
    		<dependency>
    		    <groupId>org.hibernate</groupId>
    		    <artifactId>hibernate-core</artifactId>
    		    <version>${hibernate.version}</version>
    		</dependency>
    		<dependency>
    		    <groupId>org.hibernate</groupId>
    		    <artifactId>hibernate-entitymanager</artifactId>
    		    <version>${hibernate.version}</version>
    		</dependency>

     

    然后有以下几种方式,选择一种合适自己的。

    方法一:

    增加配置文件HibernateConfig.java:

    package com.testSSH.config;
    
    import javax.persistence.EntityManagerFactory;
    
    import org.hibernate.SessionFactory;
    import org.springframework.beans.factory.annotation.Qualifier;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    @Configuration
    public class HibernateConfig {
        
        @Bean
        public SessionFactory sessionFactory(@Qualifier("entityManagerFactory") EntityManagerFactory emf){
             return emf.unwrap(SessionFactory.class);
         }
    
    }

    如果要使用@Transactional则需要在application.properties中加上:

    spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext

     

    方法二:(推荐)

    在SpringBoot的启动类中加上:

    	@Bean
    	public SessionFactory sessionFactory(HibernateEntityManagerFactory hemf) {
    	    return hemf.getSessionFactory();
    	}

    如果要使用@Transactional则需要在application.properties中加上:

    spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext

     

     

    方法三:

    在SpringBoot的启动类中加上:

        @Bean
        public HibernateJpaSessionFactoryBean sessionFactory() {
            return new HibernateJpaSessionFactoryBean();
        }

    如果要使用@Transactional则需要在application.properties中加上:

    spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext

     

     

    使用方法:

    @Autowired
    private SessionFactory sessionFactory;