Size: 44408
Comment:
|
Size: 49543
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 1422: | Line 1422: |
logback-spring.html {{{ <?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- <include resource="org/springframework/boot/logging/logback/defaults.xml" /> <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/> <include resource="org/springframework/boot/logging/logback/file-appender.xml" /> --> <!-- override spring logback default behaviour --> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <file>${filelog}</file> <encoder> <pattern>%date{ISO8601} [%thread] %-5level %logger{35} - %msg%n</pattern> </encoder> </appender> <appender name="GREETFILE" class="ch.qos.logback.core.FileAppender"> <file>/tmp/greet.log</file> <encoder> <pattern>%date{ISO8601} [%thread] %-5level %logger{35} - %msg%n</pattern> </encoder> </appender> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern>%yellow(%date{ISO8601}) %green([%thread]) %highlight(%-5level) %cyan(%logger{35}) - %white(%msg%n) </Pattern> </layout> </appender> <root level="INFO"> <appender-ref ref="FILE" /> <appender-ref ref="CONSOLE"/> </root> <logger name="hello.GreetingController" level="debug" additivity="false"> <appender-ref ref="GREETFILE"/> <appender-ref ref="CONSOLE" /> </logger> </configuration> }}} application.properties {{{ logging.file=/tmp/testout.log server.port=8443 foo.bar=bohica instance.name=node1 keystore.file=springboot.p12 keystore.password=???? keystore.type=PKCS12 keystore.alias=springboot db.driverclass=org.mariadb.jdbc.Driver db.jdbcurl=jdbc:mariadb://localhost:3306/springmvchtml db.username=usertest db.password=???? db.initialsizeconnpool=3 #rabbimq parameters rabbitmq.uri=amqp://????:????@localhost:5672 #redis spring.redis.host=localhost spring.redis.password=???????? spring.redis.port=6379 }}} pom.xml {{{ <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>hello</groupId> <artifactId>test-spring-boot</artifactId> <version>0.1.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.0.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.mariadb.jdbc</groupId> <artifactId>mariadb-java-client</artifactId> <version>1.4.4</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency> <!-- http session redis --> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session</artifactId> <version>1.2.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- http session redis --> </dependencies> <properties> <start-class>hello.Application</start-class> </properties> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestone</id> <url>http://repo.spring.io/libs-release</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-milestone</id> <url>http://repo.spring.io/libs-release</url> </pluginRepository> </pluginRepositories> </project> }}} |
SpringBoot
Example
pom.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
4 <modelVersion>4.0.0</modelVersion>
5 <groupId>hello</groupId>
6 <artifactId>test-spring-boot</artifactId>
7 <version>0.1.0</version>
8 <parent>
9 <groupId>org.springframework.boot</groupId>
10 <artifactId>spring-boot-starter-parent</artifactId>
11 <version>1.4.0.RELEASE</version>
12 </parent>
13 <dependencies>
14 <dependency>
15 <groupId>org.springframework.boot</groupId>
16 <artifactId>spring-boot-starter-thymeleaf</artifactId>
17 </dependency>
18 <dependency>
19 <groupId>org.mariadb.jdbc</groupId>
20 <artifactId>mariadb-java-client</artifactId>
21 <version>1.4.4</version>
22 </dependency>
23 <dependency>
24 <groupId>commons-dbcp</groupId>
25 <artifactId>commons-dbcp</artifactId>
26 <version>1.4</version>
27 </dependency>
28
29 <dependency>
30 <groupId>org.springframework</groupId>
31 <artifactId>spring-jdbc</artifactId>
32 <version>4.3.2.RELEASE</version>
33 </dependency>
34
35 </dependencies>
36 <properties>
37 <start-class>hello.Application</start-class>
38 </properties>
39 <build>
40 <plugins>
41 <plugin>
42 <groupId>org.springframework.boot</groupId>
43 <artifactId>spring-boot-maven-plugin</artifactId>
44 </plugin>
45 </plugins>
46 </build>
47 <repositories>
48 <repository>
49 <id>spring-milestone</id>
50 <url>http://repo.spring.io/libs-release</url>
51 </repository>
52 </repositories>
53 <pluginRepositories>
54 <pluginRepository>
55 <id>spring-milestone</id>
56 <url>http://repo.spring.io/libs-release</url>
57 </pluginRepository>
58 </pluginRepositories>
59 </project>
src/main/java/hello/GreetingController.java
1 package hello;
2
3 import org.springframework.stereotype.Controller;
4 import org.springframework.ui.Model;
5 import org.springframework.web.bind.annotation.RequestMapping;
6 import org.springframework.web.bind.annotation.RequestParam;
7
8 import org.slf4j.Logger;
9 import org.slf4j.LoggerFactory;
10 import org.springframework.web.bind.annotation.ResponseBody;
11 import org.springframework.beans.factory.annotation.Autowired;
12
13 import java.util.List;
14 import java.util.ArrayList;
15
16 @Controller
17 public class GreetingController {
18 private final Logger logger = LoggerFactory.getLogger(GreetingController.class);
19 @Autowired
20 DummyDAO dummyDAO;
21
22 public GreetingController(){
23 logger.debug("Greeting controller created.");
24 }
25
26 @RequestMapping("/greeting")
27 // http://localhost:8080/greeting?name=nnnn
28 public String greeting(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model) {
29 logger.info("Greeting endpoint called.");
30 model.addAttribute("name", name);
31 return "greeting";
32 }
33
34 @RequestMapping(value="/dummy",produces="application/json")
35 @ResponseBody
36 // http://localhost:8080/dummy
37 public List<Dummy> dummy(){
38 List<Dummy> list= new java.util.ArrayList<Dummy>();
39 Dummy dummy = new Dummy();
40 dummy.setFieldA("AAA");
41 dummy.setFieldB("CCC");
42 list.add(dummy);
43
44 Dummy dummy2 = new Dummy();
45 dummy2.setFieldA("AAA2");
46 dummy2.setFieldB("CCC2");
47 list.add(dummy2);
48
49 return list;
50 }
51
52 @RequestMapping(value="/dummyname",produces="application/json")
53 @ResponseBody
54 // http://localhost:8080/dummyname
55 public String getDummyName(){
56 return dummyDAO.getNameFromDummy();
57 }
58
59
60 }
src/main/java/hello/Application.java
1 package hello;
2
3 import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
4 import org.springframework.boot.SpringApplication;
5 import org.springframework.context.annotation.ComponentScan;
6 import org.springframework.context.annotation.Bean;
7 import org.springframework.beans.factory.annotation.Autowired;
8 import org.springframework.beans.factory.annotation.Qualifier;
9
10 import org.apache.commons.dbcp.BasicDataSource;
11 import org.springframework.jdbc.core.JdbcTemplate;
12
13 import org.slf4j.Logger;
14 import org.slf4j.LoggerFactory;
15
16 @ComponentScan
17 @EnableAutoConfiguration
18 public class Application {
19 private static Logger logger;
20
21 public static void main(String[] args) {
22 logger = LoggerFactory.getLogger(Application.class);
23 logger.info("Starting application");
24 SpringApplication.run(Application.class, args);
25 }
26
27 @Bean(name="basicDataSource",destroyMethod="close")
28 public BasicDataSource createBasicDataSource(){
29 logger.info("Creating basicDataSource");
30 BasicDataSource bds = new BasicDataSource();
31 bds.setDriverClassName("org.mariadb.jdbc.Driver");
32 bds.setUrl("jdbc:mariadb://localhost:3306/springmvchtml");
33 bds.setUsername("usertest");
34 bds.setPassword("usertest");
35 bds.setInitialSize(3);
36 return bds;
37 }
38 /*
39 @Bean(name="jdbcTemplate")
40 public JdbcTemplate jdbcTemplate(){
41 logger.info("Creating jdbcTemplate");
42 return new JdbcTemplate( basicDataSource() );
43 }
44 */
45 @Bean(name="jdbcTemplate")
46 public JdbcTemplate createJdbcTemplate(@Autowired @Qualifier("basicDataSource") BasicDataSource bds ){
47 logger.info("Creating jdbcTemplate");
48 return new JdbcTemplate( bds );
49 }
50
51 }
src/main/java/hello/ThreadTimer.java
1 package hello;
2
3 import org.springframework.stereotype.Component;
4 import javax.annotation.PostConstruct;
5 import org.springframework.beans.factory.annotation.Autowired;
6 import java.text.MessageFormat;
7 import org.slf4j.Logger;
8 import org.slf4j.LoggerFactory;
9 import java.util.ArrayList;
10
11 @Component
12 public class ThreadTimer extends Thread {
13 private int delaySeconds;
14 private Logger logger;
15 private boolean running;
16 private Object monitor=new Object();
17 private ArrayList<Object> subscribers;
18
19 //@Autowired
20 //WaitThread waitThread;
21
22 public ThreadTimer() {
23 this.logger = LoggerFactory.getLogger(ThreadTimer.class);
24 logger.info("Created instance of " + this.getClass().getSimpleName());
25 this.running = true;
26 this.delaySeconds = 5 * 1000;
27 this.setName(this.getClass().getSimpleName() + "_" + this.getName());
28 this.subscribers = new ArrayList<Object>();
29 }
30
31 public void addSubscriber(Object subscriber){
32 this.subscribers.add(subscriber);
33 }
34
35 @PostConstruct
36 public void init() {
37 logger.info("Starting the thread");
38 this.start();
39 }
40
41 @Override
42 public void run() {
43 while (running) {
44 try {
45 Thread.sleep(this.delaySeconds);
46 logger.info("Delay " + this.getClass().getSimpleName());
47
48 for(Object o: this.subscribers){
49 synchronized(o){
50 o.notify();
51 }
52 }
53 }
54 catch (InterruptedException e) {
55 logger.info("ThreadTimer interrupted exception:" + e.getMessage() );
56 }
57 catch (Exception e) {
58 e.printStackTrace();
59 logger.info("ThreadTimer exception:" + e.getMessage() );
60 stopRunning();
61 }
62 }
63 logger.info("Exited " + this.getClass().getSimpleName());
64 }
65
66 public void startRunning() {
67 this.running = true;
68 }
69
70 public void stopRunning() {
71 this.running = false;
72 }
73
74 public void destroy(){
75 logger.info("Called destroy");
76 this.stopRunning();
77 this.interrupt();
78 }
79 }
src/main/java/hello/WaitThread.java
1 package hello;
2
3 import org.springframework.stereotype.Component;
4 import javax.annotation.PostConstruct;
5 import java.text.MessageFormat;
6 import org.slf4j.Logger;
7 import org.slf4j.LoggerFactory;
8 import org.springframework.beans.factory.annotation.Autowired;
9
10 @Component
11 public class WaitThread extends Thread {
12 private Logger logger;
13 private boolean running;
14 private Object monitor;
15
16 @Autowired
17 ThreadTimer timerThread;
18
19 public WaitThread() {
20 this.logger = LoggerFactory.getLogger(WaitThread.class);
21 logger.info("Created instance of " + this.getClass().getSimpleName());
22 this.running = true;
23 this.setName(this.getClass().getSimpleName() + "_" + this.getName());
24 this.monitor=new Object();
25 }
26
27 @PostConstruct
28 public void init() {
29 this.timerThread.addSubscriber(this);
30 logger.info("Starting the thread");
31 this.start();
32 }
33
34 public void run() {
35 while (running) {
36 try {
37 synchronized(this){
38 this.wait();
39 logger.info("Notification received.");
40 }
41 }
42 catch (InterruptedException e) {
43 logger.info("ThreadTimer interrupted exception:" + e.getMessage() );
44 }
45 catch (Exception e) {
46 logger.info("WaitThread exception:" + e.getMessage() );
47 stopRunning();
48 }
49 }
50 logger.info("Exited " + this.getClass().getSimpleName());
51 }
52
53 public void startRunning() {
54 this.running = true;
55 }
56
57 public void stopRunning() {
58 this.running = false;
59 }
60
61 public void destroy(){
62 logger.info("Called destroy");
63 this.stopRunning();
64 this.interrupt();
65 }
66 }
src/main/java/hello/Dummy.java
1 package hello;
2
3 public class Dummy{
4 private String fieldA;
5 private String fieldB;
6
7 public Dummy(){
8 }
9
10 public String getFieldA(){
11 return fieldA;
12 }
13
14 public String getFieldB(){
15 return fieldB;
16 }
17
18 public void setFieldA(String arg){
19 fieldA = arg;
20 }
21
22 public void setFieldB(String arg){
23 fieldB = arg;
24 }
25 }
src/main/java/hello/DummyDAO.java
1 package hello;
2
3 import org.slf4j.Logger;
4 import org.slf4j.LoggerFactory;
5
6 import org.springframework.beans.factory.annotation.Autowired;
7 import org.springframework.beans.factory.annotation.Qualifier;
8 import org.springframework.jdbc.core.JdbcTemplate;
9 import org.springframework.stereotype.Component;
10
11 @Component
12 public class DummyDAO {
13 @Autowired
14 @Qualifier("jdbcTemplate")
15 private JdbcTemplate jdbcTemplate;
16 private Logger logger;
17
18 public DummyDAO() {
19 logger = LoggerFactory.getLogger(DummyDAO.class);
20 logger.info("Created " + this.getClass().getSimpleName());
21 }
22
23 public String getNameFromDummy() {
24 return this.jdbcTemplate.queryForObject("select name from dummy limit 1", String.class);
25 }
26 }
src/main/resources/templates/greeting.html
src/main/resources/application.properties
1 logging.file=/tmp/testout.log
src/main/resources/logback-spring.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <configuration>
3 <!--
4 <include resource="org/springframework/boot/logging/logback/defaults.xml" />
5 <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
6 <include resource="org/springframework/boot/logging/logback/file-appender.xml" />
7 -->
8 <!-- override spring logback default behaviour -->
9 <appender name="FILE" class="ch.qos.logback.core.FileAppender">
10 <file>${filelog}</file>
11 <encoder>
12 <pattern>%date{ISO8601} [%thread] %-5level %logger{35} - %msg%n</pattern>
13 </encoder>
14 </appender>
15
16 <appender name="GREETFILE" class="ch.qos.logback.core.FileAppender">
17 <file>/tmp/greet.log</file>
18 <encoder>
19 <pattern>%date{ISO8601} [%thread] %-5level %logger{35} - %msg%n</pattern>
20 </encoder>
21 </appender>
22
23 <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
24 <layout class="ch.qos.logback.classic.PatternLayout">
25 <Pattern>%yellow(%date{ISO8601}) %green([%thread]) %highlight(%-5level) %cyan(%logger{35}) - %white(%msg%n) </Pattern>
26 </layout>
27 </appender>
28
29 <root level="INFO">
30 <appender-ref ref="FILE" />
31 <appender-ref ref="CONSOLE"/>
32 </root>
33
34 <logger name="hello.GreetingController" level="debug" additivity="false">
35 <appender-ref ref="GREETFILE"/>
36 <appender-ref ref="CONSOLE" />
37 </logger>
38
39 </configuration>
src/main/resources/test.sql
1 --JDBC URL: jdbc:mariadb://localhost:3306/springmvchtml
2 --mysql -u root -p
3 create database springmvchtml;
4 create user 'usertest'@'%' identified by '????????';
5 create user 'usertest'@'localhost' identified by '????????';
6 grant all on springmvchtml.* to 'usertest'@'%';
7 grant all on springmvchtml.* to 'usertest'@'localhost';
8 show grants for 'usertest'@'%';
9 show grants for 'usertest'@'localhost';
10 create table springmvchtml.dummy (name varchar(255) ) ;
11 insert into springmvchtml.dummy (name) values('aaaa');
12 insert into springmvchtml.dummy (name) values('bbbb');
13 commit;
14 -- mysql -u usertest -p
15
JAR files list
- jar tf target/test-spring-boot-0.1.0.jar | grep "\.jar"
BOOT-INF/lib/jackson-core-2.8.1.jar BOOT-INF/lib/spring-web-4.3.2.RELEASE.jar BOOT-INF/lib/unbescape-1.1.0.RELEASE.jar BOOT-INF/lib/javassist-3.20.0-GA.jar BOOT-INF/lib/mariadb-java-client-1.4.4.jar BOOT-INF/lib/jul-to-slf4j-1.7.21.jar BOOT-INF/lib/groovy-2.4.7.jar BOOT-INF/lib/hibernate-validator-5.2.4.Final.jar BOOT-INF/lib/classmate-1.3.1.jar BOOT-INF/lib/tomcat-embed-el-8.5.4.jar BOOT-INF/lib/tomcat-embed-core-8.5.4.jar BOOT-INF/lib/commons-pool-1.6.jar BOOT-INF/lib/thymeleaf-spring4-2.1.5.RELEASE.jar BOOT-INF/lib/spring-context-4.3.2.RELEASE.jar BOOT-INF/lib/thymeleaf-2.1.5.RELEASE.jar BOOT-INF/lib/spring-boot-starter-tomcat-1.4.0.RELEASE.jar BOOT-INF/lib/thymeleaf-layout-dialect-1.4.0.jar BOOT-INF/lib/spring-boot-autoconfigure-1.4.0.RELEASE.jar BOOT-INF/lib/snakeyaml-1.17.jar BOOT-INF/lib/spring-boot-starter-web-1.4.0.RELEASE.jar BOOT-INF/lib/spring-boot-starter-logging-1.4.0.RELEASE.jar BOOT-INF/lib/spring-webmvc-4.3.2.RELEASE.jar BOOT-INF/lib/spring-beans-4.3.2.RELEASE.jar BOOT-INF/lib/slf4j-api-1.7.21.jar BOOT-INF/lib/spring-jdbc-4.3.2.RELEASE.jar BOOT-INF/lib/jackson-annotations-2.8.1.jar BOOT-INF/lib/commons-dbcp-1.4.jar BOOT-INF/lib/ognl-3.0.8.jar BOOT-INF/lib/spring-boot-starter-1.4.0.RELEASE.jar BOOT-INF/lib/tomcat-embed-websocket-8.5.4.jar BOOT-INF/lib/spring-boot-starter-thymeleaf-1.4.0.RELEASE.jar BOOT-INF/lib/spring-tx-4.3.2.RELEASE.jar BOOT-INF/lib/logback-classic-1.1.7.jar BOOT-INF/lib/spring-boot-1.4.0.RELEASE.jar BOOT-INF/lib/spring-expression-4.3.2.RELEASE.jar BOOT-INF/lib/logback-core-1.1.7.jar BOOT-INF/lib/validation-api-1.1.0.Final.jar BOOT-INF/lib/spring-core-4.3.2.RELEASE.jar BOOT-INF/lib/jackson-databind-2.8.1.jar BOOT-INF/lib/jcl-over-slf4j-1.7.21.jar BOOT-INF/lib/log4j-over-slf4j-1.7.21.jar BOOT-INF/lib/spring-aop-4.3.2.RELEASE.jar BOOT-INF/lib/jboss-logging-3.3.0.Final.jar
Add HTTPS/SSL support
Keystore creation
#create keystore with key springboot keytool -genkey -alias springboot -storetype PKCS12 -keyalg RSA -keysize 2048 -keystore springboot.p12 -validity 3650 Enter keystore password: 12345678 Re-enter new password: 12345678 What is your first and last name? [Unknown]: Spring Boot What is the name of your organizational unit? [Unknown]: Boot What is the name of your organization? [Unknown]: Boot What is the name of your City or Locality? [Unknown]: Lisbon What is the name of your State or Province? [Unknown]: Estremadura What is the two-letter country code for this unit? [Unknown]: PT Is CN=Spring Boot, OU=Boot, O=Boot, L=Lisbon, ST=Estremadura, C=PT correct? [no]: yes #list keys keytool -list -v -keystore springboot.p12 -storetype pkcs12
Code to add in Application class/configuration
// import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer; // import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer; // import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; // import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer; // import java.io.FileNotFoundException; // import org.apache.catalina.connector.Connector; // import org.springframework.beans.factory.annotation.Value; // import javax.inject.Inject; // import org.springframework.util.ResourceUtils; public class TCC implements TomcatConnectorCustomizer{ private String keystoreFile; private String keystorePassword; private String keystoreType; private String keystoreAlias; public TCC(String keystoreFile, String keystorePassword, String keystoreType, String keystoreAlias){ this.keystoreFile=keystoreFile; this.keystorePassword=keystorePassword; this.keystoreType=keystoreType; this.keystoreAlias=keystoreAlias; } public void customize(Connector connector){ connector.setSecure(true); connector.setScheme("https"); connector.setAttribute("keystoreFile", keystoreFile); connector.setAttribute("keystorePass", keystorePassword); connector.setAttribute("keystoreType", keystoreType); connector.setAttribute("keyAlias", keystoreAlias); connector.setAttribute("clientAuth", "false"); connector.setAttribute("sslProtocol", "TLS"); connector.setAttribute("SSLEnabled", true); } } public class ESCC implements EmbeddedServletContainerCustomizer{ private String keystoreFile; private String keystorePassword; private String keystoreType; private String keystoreAlias; public ESCC(String keystoreFile, String keystorePassword, String keystoreType, String keystoreAlias){ this.keystoreFile=keystoreFile; this.keystorePassword=keystorePassword; this.keystoreType=keystoreType; this.keystoreAlias=keystoreAlias; } public void customize(ConfigurableEmbeddedServletContainer container){ TomcatEmbeddedServletContainerFactory containerFactory = (TomcatEmbeddedServletContainerFactory) container; TomcatConnectorCustomizer tcc = new TCC(keystoreFile,keystorePassword,keystoreType,keystoreAlias); containerFactory.addConnectorCustomizers(tcc); } } @Bean @Inject public EmbeddedServletContainerCustomizer containerCustomizer( @Value("${keystore.file}") String keystoreFile, @Value("${keystore.password}") String keystorePassword, @Value("${keystore.type}") String keystoreType, @Value("${keystore.alias}") String keystoreAlias) throws FileNotFoundException { final String absoluteKeystoreFile = ResourceUtils.getFile(keystoreFile).getAbsolutePath(); EmbeddedServletContainerCustomizer escc = new ESCC(absoluteKeystoreFile,keystorePassword,keystoreType,keystoreAlias); return escc; }
pom.xml
<!-- Add dependency to support @Inject annotation --> <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency>
- Add server.port=8443 to application.properties or use system property -Dserver.port=8443
- Run java -Dfilelog=/tmp/out.log -Dkeystore.file=springboot.p12 -Dkeystore.password=12345678 -Dkeystore.type=PKCS12 -Dkeystore.alias=springboot -jar target/test-spring-boot-0.1.0.jar
Environment variables
src/main/resources/application.properties
logging.file=/tmp/testout.log server.port=8443 foo.bar=bohica
1 import org.springframework.core.env.Environment;
2 import org.springframework.beans.factory.annotation.Value;
3 //....................
4 @Resource
5 Environment env;
6 @Value("${foo.bar}")
7 private String fooBar;
8
9 @RequestMapping(value="/env",produces="application/json")
10 @ResponseBody
11 public List<String> getEnv(){
12 List<String> ret = new ArrayList<String>();
13 ret.add( env.getProperty("foo.bar") );
14 ret.add(fooBar);
15 return ret;
16 }
17 //....................
18
Override value in application.properties
- java -jar target/test-spring-boot-0.1.0.jar --foo.bar=snafu
Instead of using @Autowired or @Inject use @Resource (javax.annotation.Resource).
Example JPA RabbitMQ HttpSession Redis
WaitThread.java
package hello; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import java.text.MessageFormat; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @Component public class WaitThread extends Thread { private Logger logger; private boolean running; private Object monitor; @Autowired ThreadTimer timerThread; public WaitThread() { this.logger = LoggerFactory.getLogger(WaitThread.class); logger.info("Created instance of " + this.getClass().getSimpleName()); this.running = true; this.setName(this.getClass().getSimpleName() + "_" + this.getName()); this.monitor=new Object(); } @PostConstruct public void init() { this.timerThread.addSubscriber(this); logger.info("Starting the thread"); this.start(); } public void run() { while (running) { try { synchronized(this){ this.wait(); logger.info("Notification received."); } } catch (InterruptedException e) { logger.info("ThreadTimer interrupted exception:" + e.getMessage() ); } catch (Exception e) { logger.info("WaitThread exception:" + e.getMessage() ); stopRunning(); } } logger.info("Exited " + this.getClass().getSimpleName()); } public void startRunning() { this.running = true; } public void stopRunning() { this.running = false; } public void destroy(){ logger.info("Called destroy"); this.stopRunning(); this.interrupt(); } }
ThreadTimer.java
package hello; import org.springframework.stereotype.Component; import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import java.text.MessageFormat; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.ArrayList; @Component public class ThreadTimer extends Thread { private int delaySeconds; private Logger logger; private boolean running; private Object monitor=new Object(); private ArrayList<Object> subscribers; public ThreadTimer() { this.logger = LoggerFactory.getLogger(ThreadTimer.class); logger.info("Created instance of " + this.getClass().getSimpleName()); this.running = true; this.delaySeconds = 5 * 1000; this.setName(this.getClass().getSimpleName() + "_" + this.getName()); this.subscribers = new ArrayList<Object>(); } public void addSubscriber(Object subscriber){ this.subscribers.add(subscriber); } @PostConstruct public void init() { logger.info("Starting the thread"); this.start(); } @Override public void run() { while (running) { try { Thread.sleep(this.delaySeconds); logger.info("Delay " + this.getClass().getSimpleName()); for(Object o: this.subscribers){ synchronized(o){ o.notify(); } } } catch (InterruptedException e) { logger.info("ThreadTimer interrupted exception:" + e.getMessage() ); } catch (Exception e) { e.printStackTrace(); logger.info("ThreadTimer exception:" + e.getMessage() ); stopRunning(); } } logger.info("Exited " + this.getClass().getSimpleName()); } public void startRunning() { this.running = true; } public void stopRunning() { this.running = false; } public void destroy(){ logger.info("Called destroy"); this.stopRunning(); this.interrupt(); } }
MessageHandler.java
package hello; import java.nio.charset.StandardCharsets; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class MessageHandler{ private final Logger logger = LoggerFactory.getLogger(MessageHandler.class); public void handleMessage(byte[] message){ String msg = new String(message, StandardCharsets.UTF_8); logger.info("Received msg " + msg ); } public void handleMessage(String message){ logger.info("Received msg " + message ); } }
GreetingController.java
package hello; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.beans.factory.annotation.Autowired; import java.util.List; import java.util.ArrayList; import org.springframework.web.bind.annotation.PathVariable; //import javax.inject.Inject; import org.springframework.core.env.Environment; import org.springframework.beans.factory.annotation.Value; import javax.annotation.Resource; import org.springframework.amqp.rabbit.core.RabbitTemplate; import javax.servlet.http.HttpSession; @Controller public class GreetingController { private final Logger logger = LoggerFactory.getLogger(GreetingController.class); @Resource DummyDAO dummyDAO; @Resource Environment env; @Resource RabbitTemplate rabbitTemplate; @Value("${instance.name}") String instanceName; public GreetingController(){ logger.debug("Greeting controller created."); } @RequestMapping("/greeting") public String greeting(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model ) { model.addAttribute("name", name); rabbitTemplate.convertAndSend("topicExchange","myQueue", name ); rabbitTemplate.convertAndSend("fanoutExchange","", name ); return "greeting"; } @RequestMapping("/setvalue/{value}") @ResponseBody public String setValue(@PathVariable("value") String value, Model model,HttpSession httpSession) { httpSession.setAttribute("name", value ); return httpSession.getId(); } @RequestMapping("/getvalue") @ResponseBody public String setValue(Model model,HttpSession httpSession) { return (String) httpSession.getAttribute("name"); } @RequestMapping("/instancename") @ResponseBody public String setValue(Model model) { return this.instanceName; } @RequestMapping("/greeting/add/{name}") public String addGreeting(@PathVariable("name") String name, Model model) { model.addAttribute("name", name); dummyDAO.addName(name); return "greeting"; } @RequestMapping(value="/dummy",produces="application/json") @ResponseBody public List<DummyJPA> dummy(){ return dummyDAO.getAllNames(); } @RequestMapping(value="/dummyname",produces="application/json") @ResponseBody public String getDummyName(){ return dummyDAO.getNameFromDummy(); } @Value("${foo.bar}") private String fooBar; @RequestMapping(value="/env",produces="application/json") @ResponseBody public List<String> getEnv(){ List<String> ret = new ArrayList<String>(); ret.add( env.getProperty("foo.bar") ); ret.add(fooBar); return ret; } }
DummyJPA.java
package hello; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.NamedQuery; import javax.persistence.NamedQueries; @Entity @NamedQueries({ @NamedQuery(name="DummyJPA.getAll", query="Select e From DummyJPA e") }) public class DummyJPA{ @Id @GeneratedValue(strategy=GenerationType.AUTO) private Long id; private String dummy; public DummyJPA(){ } public String getDummy(){ return this.dummy; } public void setDummy(String dummy){ this.dummy=dummy; } @Override public String toString(){ return String.format("Dummy %s", this.dummy); } }
DummyDAO.java
package hello; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component; import javax.persistence.PersistenceContext; import javax.persistence.EntityManager; import javax.persistence.Query; import javax.transaction.Transactional; import java.util.List; @Component public class DummyDAO { @Autowired @Qualifier("jdbcTemplate") private JdbcTemplate jdbcTemplate; private Logger logger; @PersistenceContext(unitName="default") EntityManager em; public DummyDAO() { logger = LoggerFactory.getLogger(DummyDAO.class); logger.info("Created " + this.getClass().getSimpleName()); } public String getNameFromDummy() { return this.jdbcTemplate.queryForObject("select name from dummy limit 1", String.class); } @Transactional public void addName(String name){ DummyJPA djpa = new DummyJPA(); djpa.setDummy(name); em.persist(djpa); } @Transactional public List<DummyJPA> getAllNames(){ return em.createNamedQuery("DummyJPA.getAll",DummyJPA.class).getResultList(); } }
Dummy.java
package hello; public class Dummy{ private String fieldA; private String fieldB; public Dummy(){ } public String getFieldA(){ return fieldA; } public String getFieldB(){ return fieldB; } public void setFieldA(String arg){ fieldA = arg; } public void setFieldB(String arg){ fieldB = arg; } }
ConfigHttpSession.java
/* http://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot.html pkg install redis #freebsd add redis_enable="YES" to /etc/rc.conf /usr/local/etc/rc.d/redis start /usr/local/etc/redis.conf requirepass 12345678 keys * hgetall <hashkey> Same as in application.properties spring.redis.password=12345678 https://localhost:8443/setvalue/valx 147569e4-9e6d-4363-a373-b20261513f11 https://localhost:8443/getvalue SESSION=147569e4-9e6d-4363-a373-b20261513f11 2 instances of spring boot using the same redis server curl -k -v --cookie "SESSION=147569e4-9e6d-4363-a373-b20261513f11" https://localhost:8443/getvalue curl -k -v --cookie "SESSION=147569e4-9e6d-4363-a373-b20261513f11" https://localhost:8444/getvalue */ package hello; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; @EnableRedisHttpSession public class ConfigHttpSession{ // springSessionRepositoryFilterbean is responsible for replacing the HttpSession with a custom implementation that is backed by Spring Session. }
package hello; import java.nio.charset.StandardCharsets; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class BroadcastMessageHandler{ private final Logger logger = LoggerFactory.getLogger(BroadcastMessageHandler.class); public void handleMessage(byte[] message){ String msg = new String(message, StandardCharsets.UTF_8); logger.info("Received msg " + msg ); } public void handleMessage(String message){ logger.info("Received msg " + message ); } }
Application.java
package hello; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Bean; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.apache.commons.dbcp.BasicDataSource; import org.springframework.jdbc.core.JdbcTemplate; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.boot.autoconfigure.domain.EntityScan; import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer; import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer; import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer; import java.io.FileNotFoundException; import org.apache.catalina.connector.Connector; import org.springframework.beans.factory.annotation.Value; import javax.inject.Inject; import javax.annotation.Resource; import org.springframework.util.ResourceUtils; import org.springframework.core.env.Environment; //-- rabbit import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.Queue; import org.springframework.amqp.core.TopicExchange; import org.springframework.amqp.core.FanoutExchange; import org.springframework.amqp.core.AnonymousQueue; import org.springframework.amqp.rabbit.connection.ConnectionFactory; import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer; import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter; import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; import java.net.URI; //-- rabbit @ComponentScan @EnableAutoConfiguration @EntityScan(basePackages="hello") public class Application { @Resource Environment env; private static Logger logger; public static void main(String[] args) { logger = LoggerFactory.getLogger(Application.class); logger.info("Starting application"); SpringApplication.run(Application.class, args); } @Bean(name="basicDataSource",destroyMethod="close") public BasicDataSource createBasicDataSource(){ logger.info("Creating basicDataSource"); BasicDataSource bds = new BasicDataSource(); // get config data from application.properties bds.setDriverClassName(env.getProperty("db.driverclass") ); bds.setUrl(env.getProperty("db.jdbcurl") ); bds.setUsername( env.getProperty("db.username") ); bds.setPassword( env.getProperty("db.password") ); bds.setInitialSize( Integer.parseInt( env.getProperty("db.initialsizeconnpool")) ); return bds; } @Bean(name="jdbcTemplate") public JdbcTemplate createJdbcTemplate(@Autowired @Qualifier("basicDataSource") BasicDataSource bds ){ logger.info("Creating jdbcTemplate"); return new JdbcTemplate( bds ); } //--- public class TCC implements TomcatConnectorCustomizer{ Environment env; public TCC(Environment env){ this.env=env; } public void customize(Connector connector){ String absoluteKeystoreFile = ""; logger.info(String.format("Keystore file: %s" , env.getProperty("keystore.file") )); try{ absoluteKeystoreFile = ResourceUtils.getFile(env.getProperty("keystore.file")).getAbsolutePath(); logger.info(String.format("Absolute path keystore: %s" , absoluteKeystoreFile ) ); } catch(Exception ex){ logger.error( ex.getMessage() ); } connector.setSecure(true); connector.setScheme("https"); connector.setAttribute("keystoreFile", absoluteKeystoreFile); connector.setAttribute("keystorePass", env.getProperty("keystore.password")); connector.setAttribute("keystoreType", env.getProperty("keystore.type")); connector.setAttribute("keyAlias", env.getProperty("keystore.alias") ); connector.setAttribute("clientAuth", "false"); connector.setAttribute("sslProtocol", "TLS"); connector.setAttribute("SSLEnabled", true); } } public class ESCC implements EmbeddedServletContainerCustomizer{ Environment env; public ESCC(Environment env){ this.env=env; } public void customize(ConfigurableEmbeddedServletContainer container){ TomcatEmbeddedServletContainerFactory containerFactory = (TomcatEmbeddedServletContainerFactory) container; TomcatConnectorCustomizer tcc = new TCC(env); containerFactory.addConnectorCustomizers(tcc); } } @Bean(name="containerCustomizer") public EmbeddedServletContainerCustomizer containerCustomizer() throws FileNotFoundException { logger.info("Creating containerCustomizer"); EmbeddedServletContainerCustomizer escc = new ESCC(env); return escc; } //--- //---- rabbit //import org.springframework.amqp.rabbit.connection.CachingConnectionFactory; @Bean(name="cachingConnectionFactory") CachingConnectionFactory createCachingConnectionFactory(){ logger.info("Creating cachingConnectionFactory"); String uri = env.getProperty("rabbitmq.uri"); URI rabbitmqUri=null; try{ rabbitmqUri = new URI(uri); } catch(Exception ex){ ex.printStackTrace(); } CachingConnectionFactory ret = new CachingConnectionFactory(rabbitmqUri); logger.info(String.format("Created cachingConnectionFactory with hashCode %d" , ret.hashCode() ) ); return ret; } @Bean(name="myQueue") Queue createMyQueue() { logger.info("Creating myQueue"); return new Queue("myQueue", false); } @Bean(name="topicExchange") TopicExchange createTopicExchange() { logger.info("Creating topicExchange"); return new TopicExchange("topicExchange"); } @Bean(name="bindingQueue") Binding binding(@Qualifier("myQueue")Queue queue, @Qualifier("topicExchange")TopicExchange exchange) { logger.info("Creating bindingQueue"); return BindingBuilder.bind(queue).to(exchange).with(queue.getName()); } @Bean(name="workQueueContainer") SimpleMessageListenerContainer createWorkQueueContainer(ConnectionFactory connectionFactory, @Autowired @Qualifier("listenerAdapter") MessageListenerAdapter listenerAdapter,@Qualifier("myQueue") Queue queue) { logger.info("Creating createWorkQueueContainer for work queue"); logger.info(String.format("Using ConnectionFactory with hashCode %d" , connectionFactory.hashCode() ) ); SimpleMessageListenerContainer smlc = new SimpleMessageListenerContainer(); smlc.setConnectionFactory(connectionFactory); smlc.setQueueNames(queue.getName() ); smlc.setMessageListener(listenerAdapter); return smlc; } @Bean(name="listenerAdapter") MessageListenerAdapter listenerAdapter(@Autowired @Qualifier("messageHandler")MessageHandler messageHandler) { logger.info("Creating listenerAdapter"); return new MessageListenerAdapter(messageHandler); } @Bean(name="messageHandler") MessageHandler createMessageHandler() { logger.info("Creating messageHandler"); return new MessageHandler(); } //-------- @Bean(name="fanoutExchange") FanoutExchange createFanoutExchange() { logger.info("Creating fanoutExchange"); return new FanoutExchange("fanoutExchange"); } @Bean(name="anonymousQueue1") AnonymousQueue createAnonymousQueue1() { logger.info("Creating anonQueue1"); return new AnonymousQueue(); } @Bean(name="bindingTopic") Binding bindingTopic(@Qualifier("anonymousQueue1")AnonymousQueue queue, @Qualifier("fanoutExchange")FanoutExchange exchange) { logger.info("Creating bindingTopic"); return BindingBuilder.bind(queue).to(exchange); } @Bean(name="broadcastMessageHandler") BroadcastMessageHandler createBroadcastMessageHandler() { logger.info("Creating broadcastMessageHandlermessageHandler"); return new BroadcastMessageHandler(); } @Bean(name="broadcastListenerAdapter") MessageListenerAdapter createBroadcastlistenerAdapter(@Autowired @Qualifier("broadcastMessageHandler")BroadcastMessageHandler broadcastMessageHandler) { logger.info("Creating broadcastListenerAdapter"); return new MessageListenerAdapter(broadcastMessageHandler); } @Bean(name="topicContainer") SimpleMessageListenerContainer createTopicContainer(ConnectionFactory connectionFactory, @Autowired @Qualifier("broadcastListenerAdapter") MessageListenerAdapter listenerAdapter, @Qualifier("anonymousQueue1") AnonymousQueue anonQueue) { logger.info("Creating container for topic"); logger.info(String.format("Using ConnectionFactory with hashCode %d" , connectionFactory.hashCode() ) ); SimpleMessageListenerContainer smlc = new SimpleMessageListenerContainer(); smlc.setConnectionFactory(connectionFactory); smlc.setQueueNames( anonQueue.getName() ); smlc.setMessageListener(listenerAdapter); return smlc; } //---- //---- rabbit }
persistence.xml
<persistence> <persistence-unit name="default" transaction-type="RESOURCE_LOCAL"> <jta-data-source>basicDataSource</jta-data-source> <properties> <!-- <property name="hibernate.hbm2ddl.auto" value="create-drop" /> --> <property name="hibernate.hbm2ddl.auto" value="update" /> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/> <property name="hibernate.show_sql" value="false" /> </properties> </persistence-unit> </persistence>
greeting.html
<!DOCTYPE HTML> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Getting Started: Serving Web Content</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> </head> <body> <p th:text="'Hello, ' + ${name} + '!'" /> </body> </html>
test.sql
--JDBC URL: jdbc:mariadb://localhost:3306/springmvchtml --mysql -u root -p create database springmvchtml; create user 'usertest'@'%' identified by '????'; create user 'usertest'@'localhost' identified by '????'; grant all on springmvchtml.* to 'usertest'@'%'; grant all on springmvchtml.* to 'usertest'@'localhost'; show grants for 'usertest'@'%'; show grants for 'usertest'@'localhost'; create table springmvchtml.dummy (name varchar(255) ) ; insert into springmvchtml.dummy (name) values('aaaa'); insert into springmvchtml.dummy (name) values('bbbb'); commit; -- mysql -u usertest -p
logback-spring.html
<?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- <include resource="org/springframework/boot/logging/logback/defaults.xml" /> <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/> <include resource="org/springframework/boot/logging/logback/file-appender.xml" /> --> <!-- override spring logback default behaviour --> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <file>${filelog}</file> <encoder> <pattern>%date{ISO8601} [%thread] %-5level %logger{35} - %msg%n</pattern> </encoder> </appender> <appender name="GREETFILE" class="ch.qos.logback.core.FileAppender"> <file>/tmp/greet.log</file> <encoder> <pattern>%date{ISO8601} [%thread] %-5level %logger{35} - %msg%n</pattern> </encoder> </appender> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern>%yellow(%date{ISO8601}) %green([%thread]) %highlight(%-5level) %cyan(%logger{35}) - %white(%msg%n) </Pattern> </layout> </appender> <root level="INFO"> <appender-ref ref="FILE" /> <appender-ref ref="CONSOLE"/> </root> <logger name="hello.GreetingController" level="debug" additivity="false"> <appender-ref ref="GREETFILE"/> <appender-ref ref="CONSOLE" /> </logger> </configuration>
application.properties
logging.file=/tmp/testout.log server.port=8443 foo.bar=bohica instance.name=node1 keystore.file=springboot.p12 keystore.password=???? keystore.type=PKCS12 keystore.alias=springboot db.driverclass=org.mariadb.jdbc.Driver db.jdbcurl=jdbc:mariadb://localhost:3306/springmvchtml db.username=usertest db.password=???? db.initialsizeconnpool=3 #rabbimq parameters rabbitmq.uri=amqp://????:????@localhost:5672 #redis spring.redis.host=localhost spring.redis.password=???????? spring.redis.port=6379
pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>hello</groupId> <artifactId>test-spring-boot</artifactId> <version>0.1.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.0.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.mariadb.jdbc</groupId> <artifactId>mariadb-java-client</artifactId> <version>1.4.4</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>4.3.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-amqp</artifactId> </dependency> <dependency> <groupId>javax.inject</groupId> <artifactId>javax.inject</artifactId> <version>1</version> </dependency> <!-- http session redis --> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session</artifactId> <version>1.2.2.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- http session redis --> </dependencies> <properties> <start-class>hello.Application</start-class> </properties> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestone</id> <url>http://repo.spring.io/libs-release</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-milestone</id> <url>http://repo.spring.io/libs-release</url> </pluginRepository> </pluginRepositories> </project>