Size: 3893
Comment:
|
Size: 69272
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 6: | Line 6: |
{{{ | {{{#!highlight xml |
Line 69: | Line 69: |
{{{ | {{{#!highlight java |
Line 96: | Line 96: |
// http://localhost:8080/greeting?name=nnnn | |
Line 104: | Line 105: |
// http://localhost:8080/dummy | |
Line 121: | Line 123: |
// http://localhost:8080/dummyname | |
Line 128: | Line 131: |
=== src/main/java/hello/Application.java === {{{#!highlight 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; @ComponentScan @EnableAutoConfiguration public class Application { 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(); bds.setDriverClassName("org.mariadb.jdbc.Driver"); bds.setUrl("jdbc:mariadb://localhost:3306/springmvchtml"); bds.setUsername("usertest"); bds.setPassword("usertest"); bds.setInitialSize(3); return bds; } /* @Bean(name="jdbcTemplate") public JdbcTemplate jdbcTemplate(){ logger.info("Creating jdbcTemplate"); return new JdbcTemplate( basicDataSource() ); } */ @Bean(name="jdbcTemplate") public JdbcTemplate createJdbcTemplate(@Autowired @Qualifier("basicDataSource") BasicDataSource bds ){ logger.info("Creating jdbcTemplate"); return new JdbcTemplate( bds ); } } }}} === src/main/java/hello/ThreadTimer.java === {{{#!highlight 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; //@Autowired //WaitThread waitThread; 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(); } } }}} === src/main/java/hello/WaitThread.java === {{{#!highlight 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(); } } }}} === src/main/java/hello/Dummy.java === {{{#!highlight 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; } } }}} === src/main/java/hello/DummyDAO.java === {{{#!highlight 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; @Component public class DummyDAO { @Autowired @Qualifier("jdbcTemplate") private JdbcTemplate jdbcTemplate; private Logger logger; 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); } } }}} === src/main/resources/templates/greeting.html === {{{#!highlight 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> }}} === src/main/resources/application.properties === {{{#!highlight sh logging.file=/tmp/testout.log }}} === src/main/resources/logback-spring.xml === {{{#!highlight xml <?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> }}} === src/main/resources/test.sql === {{{#!highlight 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 }}} === 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 {{{#!highlight java // 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 {{{#!highlight 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 * Access https://localhost:8443/greeting?name=x == Environment variables == src/main/resources/application.properties {{{ logging.file=/tmp/testout.log server.port=8443 foo.bar=bohica }}} {{{#!highlight java import org.springframework.core.env.Environment; import org.springframework.beans.factory.annotation.Value; //.................... @Resource Environment env; @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; } //.................... }}} Override value in application.properties * java -jar target/test-spring-boot-0.1.0.jar --foo.bar=snafu It's also possible to override values with environment variables as for example * FOO_BAR=snafu java -jar target/test-spring-boot-0.1.0.jar The *.* should be replaced by *_* and the lowercase characters must be capitalized. Instead of using @Autowired or @Inject use @Resource (javax.annotation.Resource). == Example JPA RabbitMQ HttpSession Redis == Structure {{{ . ./pom.xml ./src ./src/main ./src/main/java ./src/main/java/hello ./src/main/java/hello/GreetingController.java ./src/main/java/hello/Application.java ./src/main/java/hello/ThreadTimer.java ./src/main/java/hello/WaitThread.java ./src/main/java/hello/Dummy.java ./src/main/java/hello/DummyDAO.java ./src/main/java/hello/DummyJPA.java ./src/main/java/hello/MessageHandler.java ./src/main/java/hello/BroadcastMessageHandler.java ./src/main/java/hello/ConfigHttpSession.java ./src/main/resources ./src/main/resources/templates ./src/main/resources/templates/greeting.html ./src/main/resources/application.properties ./src/main/resources/logback-spring.xml ./src/main/resources/test.sql ./src/main/resources/META-INF ./src/main/resources/META-INF/persistence.xml }}} WaitThread.java {{{#!highlight 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 {{{#!highlight 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 {{{#!highlight 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 {{{#!highlight 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 {{{#!highlight 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 {{{#!highlight 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 {{{#!highlight 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 {{{#!highlight 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. } }}} BroadcastMessageHandler.java {{{#!highlight java 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 {{{#!highlight 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 {{{#!highlight 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 {{{#!highlight 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 {{{#!highlight 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.xml {{{#!highlight xml <?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 {{{#!highlight 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> }}} Libs {{{#!highlight sh -rw-r--r-- 1 vitor vitor 37M Sep 29 15:49 test-spring-boot-0.1.0.jar jar tf test-spring-boot-0.1.0.jar | grep BOOT | grep jar BOOT-INF/lib/spring-session-1.2.2.RELEASE.jar BOOT-INF/lib/spring-boot-starter-data-redis-1.4.0.RELEASE.jar BOOT-INF/lib/jackson-core-2.8.1.jar BOOT-INF/lib/javassist-3.20.0-GA.jar BOOT-INF/lib/jul-to-slf4j-1.7.21.jar BOOT-INF/lib/groovy-2.4.7.jar BOOT-INF/lib/spring-amqp-1.6.1.RELEASE.jar BOOT-INF/lib/hibernate-validator-5.2.4.Final.jar BOOT-INF/lib/classmate-1.3.1.jar BOOT-INF/lib/hibernate-commons-annotations-5.0.1.Final.jar BOOT-INF/lib/tomcat-embed-el-8.5.4.jar BOOT-INF/lib/jedis-2.8.2.jar BOOT-INF/lib/httpcore-4.4.5.jar BOOT-INF/lib/antlr-2.7.7.jar BOOT-INF/lib/xml-apis-1.4.01.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/http-client-1.0.0.RELEASE.jar BOOT-INF/lib/httpclient-4.5.2.jar BOOT-INF/lib/spring-boot-starter-logging-1.4.0.RELEASE.jar BOOT-INF/lib/tomcat-jdbc-8.5.4.jar BOOT-INF/lib/spring-beans-4.3.2.RELEASE.jar BOOT-INF/lib/spring-jdbc-4.3.2.RELEASE.jar BOOT-INF/lib/spring-boot-starter-jdbc-1.4.0.RELEASE.jar BOOT-INF/lib/spring-boot-starter-amqp-1.4.0.RELEASE.jar BOOT-INF/lib/spring-aspects-4.3.2.RELEASE.jar BOOT-INF/lib/commons-dbcp-1.4.jar BOOT-INF/lib/spring-data-commons-1.12.2.RELEASE.jar BOOT-INF/lib/spring-context-support-4.3.2.RELEASE.jar BOOT-INF/lib/spring-data-keyvalue-1.1.2.RELEASE.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/commons-logging-1.2.jar BOOT-INF/lib/spring-tx-4.3.2.RELEASE.jar BOOT-INF/lib/validation-api-1.1.0.Final.jar BOOT-INF/lib/spring-core-4.3.2.RELEASE.jar BOOT-INF/lib/spring-boot-starter-aop-1.4.0.RELEASE.jar BOOT-INF/lib/spring-data-jpa-1.10.2.RELEASE.jar BOOT-INF/lib/commons-pool2-2.4.2.jar BOOT-INF/lib/dom4j-1.6.1.jar BOOT-INF/lib/tomcat-juli-8.5.4.jar BOOT-INF/lib/jcl-over-slf4j-1.7.21.jar BOOT-INF/lib/log4j-over-slf4j-1.7.21.jar BOOT-INF/lib/aspectjweaver-1.8.9.jar BOOT-INF/lib/spring-data-redis-1.7.2.RELEASE.jar BOOT-INF/lib/spring-web-4.3.2.RELEASE.jar BOOT-INF/lib/unbescape-1.1.0.RELEASE.jar BOOT-INF/lib/mariadb-java-client-1.4.4.jar BOOT-INF/lib/amqp-client-3.6.3.jar BOOT-INF/lib/spring-oxm-4.3.2.RELEASE.jar BOOT-INF/lib/tomcat-embed-core-8.5.4.jar BOOT-INF/lib/spring-orm-4.3.2.RELEASE.jar BOOT-INF/lib/hibernate-jpa-2.1-api-1.0.0.Final.jar BOOT-INF/lib/commons-pool-1.6.jar BOOT-INF/lib/thymeleaf-spring4-2.1.5.RELEASE.jar BOOT-INF/lib/hibernate-core-5.0.9.Final.jar BOOT-INF/lib/spring-context-4.3.2.RELEASE.jar BOOT-INF/lib/thymeleaf-2.1.5.RELEASE.jar BOOT-INF/lib/commons-codec-1.10.jar BOOT-INF/lib/spring-boot-starter-web-1.4.0.RELEASE.jar BOOT-INF/lib/spring-webmvc-4.3.2.RELEASE.jar BOOT-INF/lib/slf4j-api-1.7.21.jar BOOT-INF/lib/javax.inject-1.jar BOOT-INF/lib/jackson-annotations-2.8.1.jar BOOT-INF/lib/jandex-2.0.0.Final.jar BOOT-INF/lib/spring-messaging-4.3.2.RELEASE.jar BOOT-INF/lib/ognl-3.0.8.jar BOOT-INF/lib/hibernate-entitymanager-5.0.9.Final.jar BOOT-INF/lib/spring-boot-starter-thymeleaf-1.4.0.RELEASE.jar BOOT-INF/lib/spring-retry-1.1.3.RELEASE.jar BOOT-INF/lib/javax.transaction-api-1.2.jar BOOT-INF/lib/logback-classic-1.1.7.jar BOOT-INF/lib/spring-boot-starter-data-jpa-1.4.0.RELEASE.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/jackson-databind-2.8.1.jar BOOT-INF/lib/spring-rabbit-1.6.1.RELEASE.jar BOOT-INF/lib/spring-aop-4.3.2.RELEASE.jar BOOT-INF/lib/jboss-logging-3.3.0.Final.jar }}} == springTestApp == === pom.xml === {{{#!highlight 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>org.allowed.bitarus</groupId> <artifactId>springTestApp</artifactId> <version>0.1.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.2.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> <properties> <start-class>org.allowed.bitarus.springTestApp.Application</start-class> </properties> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-releases</id> <url>http://repo.spring.io/libs-release</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-releases</id> <url>http://repo.spring.io/libs-release</url> </pluginRepository> </pluginRepositories> </project> }}} === src/main/java/org/allowed/bitarus/springTestApp/Application.java === {{{#!highlight java package org.allowed.bitarus.springTestApp; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.context.annotation.ComponentScan; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import java.util.concurrent.Future; import java.util.ArrayList; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @ComponentScan @EnableAutoConfiguration @SpringBootApplication public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean(name="tasksFutures") public ArrayList<Future<Integer>> createTasksFutures(){ System.out.println("Creating tasksFutures"); return new ArrayList<Future<Integer>>(); } @Bean(name="executors") public ExecutorService createExecutors(){ return Executors.newFixedThreadPool(5); } } }}} === src/main/java/org/allowed/bitarus/springTestApp/Tasker.java === {{{#!highlight java package org.allowed.bitarus.springTestApp; import org.springframework.stereotype.Component; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @Component("tasker") public class Tasker { private ExecutorService _es; public Tasker(@Qualifier("executors") ExecutorService es){ System.out.println("Created Tasker !!!!"); _es = es; } public Future<Integer> addTask(TaskX taskx){ Future<Integer> f = _es.submit( taskx ); return f; } } }}} === src/main/java/org/allowed/bitarus/springTestApp/Receiver.java === {{{#!highlight java package org.allowed.bitarus.springTestApp; import org.springframework.stereotype.Component; import java.util.concurrent.Future; import java.util.ArrayList; import org.springframework.beans.factory.annotation.Qualifier; import javax.annotation.PostConstruct; @Component public class Receiver { private Tasker _t; private ArrayList<Future<Integer>> _tasks; public Receiver(@Qualifier("tasker")Tasker t, @Qualifier("tasksFutures") ArrayList<Future<Integer>> tasks ){ System.out.println("Created receiver !!!!"); _t = t; _tasks = tasks; // wait for all tasks ... /* boolean loop=true; while(loop){ boolean allDone=true; for(Future<Integer> f : tasks){ if(f.isDone()==false){ allDone=false; } } if(allDone){ loop=false; } try{ Thread.sleep(1000); } catch(Exception ex){ } } for(Future<Integer> f : tasks){ try{ Integer res = f.get(); System.out.println(res); } catch(Exception ex){ } } */ } @PostConstruct public void init(){ System.out.println("Init post construct"); for(int i=0;i<10;i++){ _tasks.add( _t.addTask( new TaskX(5,6) ) ); } } } }}} === TaskX.java === {{{#!highlight java package org.allowed.bitarus.springTestApp; import java.util.concurrent.Callable; public class TaskX implements Callable<Integer>{ private int _x; private int _y; public TaskX(int x,int y){ _x=x; _y=y; } public Integer call() { try { Thread.sleep(5000); } catch(Exception ex){ } int sum = _x+_y; System.out.println("TID:"+Thread.currentThread().getId() + " sumVal:" + sum ); return sum; } } }}} == Example with MongoDB == Think about using '''spring.data.mongodb.uri'''. pom.xml {{{#!highlight 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>org.allowed.bitarus</groupId> <artifactId>springTestApp</artifactId> <version>0.1.0</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.4.2.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-mongodb</artifactId> <version>1.9.6.RELEASE</version> </dependency> </dependencies> <properties> <start-class>org.allowed.bitarus.springTestApp.Application</start-class> </properties> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-releases</id> <url>http://repo.spring.io/libs-release</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-releases</id> <url>http://repo.spring.io/libs-release</url> </pluginRepository> </pluginRepositories> </project> }}} src/main/resources/application.properties {{{#!highlight bash # disable web container/server spring.main.web-environment=false threadpool.nrExecutors=5 mongox.host=127.0.0.1 mongox.port=27017 mongox.database=mydatabase }}} src/main/java/org/allowed/bitarus/springTestApp/Application.java {{{#!highlight java package org.allowed.bitarus.springTestApp; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.SpringApplication; import org.springframework.context.annotation.ComponentScan; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Bean; import java.util.concurrent.Future; import java.util.ArrayList; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import org.springframework.data.mongodb.repository.config.EnableMongoRepositories; import org.springframework.data.mongodb.core.MongoTemplate; import com.mongodb.Mongo; import org.springframework.core.env.Environment; import javax.annotation.Resource; @ComponentScan @EnableAutoConfiguration @SpringBootApplication @EnableMongoRepositories // search for MongoDB reps public class Application { @Resource Environment _env; public static void main(String[] args) { SpringApplication.run(Application.class, args); } @Bean(name="tasksFutures") public ArrayList<Future<Integer>> createTasksFutures(){ System.out.println("Creating tasksFutures"); return new ArrayList<Future<Integer>>(); } @Bean(name="executors") public ExecutorService createExecutors(){ System.out.println("Creating executors"); System.out.println(_env.getProperty("threadpool.nrExecutors")); return Executors.newFixedThreadPool(5); } @Bean(name="mongoTemplate") public MongoTemplate mongoTemplate() throws Exception { System.out.println("Creating mongoTemplate"); System.out.println(_env.getProperty("mongox.host")); System.out.println(_env.getProperty("mongox.port")); System.out.println(_env.getProperty("mongox.database")); Mongo mongo = new Mongo( _env.getProperty("mongox.host"), Integer.parseInt(_env.getProperty("mongox.port") ) ); return new MongoTemplate(mongo, _env.getProperty("mongox.database") ); } } }}} src/main/java/org/allowed/bitarus/springTestApp/Tasker.java {{{#!highlight java package org.allowed.bitarus.springTestApp; import org.springframework.stereotype.Component; import java.util.concurrent.ExecutorService; import java.util.concurrent.Future; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; @Component("tasker") public class Tasker { private ExecutorService _es; public Tasker(@Qualifier("executors") ExecutorService es){ System.out.println("Created Tasker !!!!"); _es = es; } public Future<Integer> addTask(TaskX taskx){ Future<Integer> f = _es.submit( taskx ); return f; } } }}} src/main/java/org/allowed/bitarus/springTestApp/Result.java {{{#!highlight java package org.allowed.bitarus.springTestApp; import org.springframework.data.annotation.Id; public class Result { @Id private String id; private int sumResult; public Result(){} public int getSumResult(){return this.sumResult;} public void setSumResult(int sumResult){this.sumResult=sumResult;} public String getId(){return this.id;} public void setId(String id){this.id=id;} } }}} src/main/java/org/allowed/bitarus/springTestApp/Receiver.java {{{#!highlight java package org.allowed.bitarus.springTestApp; import org.springframework.stereotype.Component; import java.util.concurrent.Future; import java.util.ArrayList; import java.util.List; import org.springframework.beans.factory.annotation.Qualifier; import javax.annotation.PostConstruct; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.query.Query; import org.springframework.data.mongodb.core.MongoTemplate; @Component public class Receiver { private Tasker _t; private ArrayList<Future<Integer>> _tasks; private ResultRepository _repository; public Receiver(@Qualifier("tasker")Tasker t, @Qualifier("tasksFutures") ArrayList<Future<Integer>> tasks, ResultRepository repository ){ System.out.println("Created receiver !!!!"); _t = t; _tasks = tasks; _repository = repository; } @Autowired private MongoTemplate mongoTemplate; @PostConstruct public void init(){ System.out.println("Init post construct"); for(int i=0;i<10;i++){ _tasks.add( _t.addTask( new TaskX(5,6) ) ); } // wait for all tasks ... boolean loop=true; while(loop){ boolean allDone=true; for(Future<Integer> f : _tasks){ if(f.isDone()==false){ allDone=false; } } if(allDone){ loop=false; } try{ Thread.sleep(1000); } catch(Exception ex){ } } for(Future<Integer> f : _tasks){ try{ Integer res = f.get(); System.out.println(res); Result r = new Result(); r.setSumResult(res); _repository.save(r); } catch(Exception ex){ } } System.out.println( _repository.count() ); List<Result> res = _repository.findBySumResult(11); for(Result r : res){ r.setSumResult((int)System.currentTimeMillis()); _repository.save(r); } System.out.println("mongoTemplateCount " + mongoTemplate.count(new Query() ,Result.class) ); } } }}} src/main/java/org/allowed/bitarus/springTestApp/ResultRepository.java {{{#!highlight java package org.allowed.bitarus.springTestApp; import java.util.List; import org.springframework.data.mongodb.repository.MongoRepository; /* Result -> class to store String -> id in collection type Collection result in database mydatabase { "_id" : ObjectId("58828e2822e1a609d96a5e52"), "_class" : "org.allowed.bitarus.springTestApp.Result", "sumResult" : 11 } */ public interface ResultRepository extends MongoRepository<Result, String> { public List<Result> findBySumResult(int sumResult); } }}} src/main/java/org/allowed/bitarus/springTestApp/TaskX.java {{{#!highlight java package org.allowed.bitarus.springTestApp; import java.util.concurrent.Callable; public class TaskX implements Callable<Integer>{ private int _x; private int _y; public TaskX(int x,int y){ _x=x; _y=y; } public Integer call() { try { Thread.sleep(5000); } catch(Exception ex){ } int sum = _x+_y; System.out.println("TID:"+Thread.currentThread().getId() + " sumVal:" + sum ); return sum; } } }}} |
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
1 // import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
2 // import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
3 // import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
4 // import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer;
5 // import java.io.FileNotFoundException;
6 // import org.apache.catalina.connector.Connector;
7 // import org.springframework.beans.factory.annotation.Value;
8 // import javax.inject.Inject;
9 // import org.springframework.util.ResourceUtils;
10
11 public class TCC implements TomcatConnectorCustomizer{
12 private String keystoreFile;
13 private String keystorePassword;
14 private String keystoreType;
15 private String keystoreAlias;
16
17 public TCC(String keystoreFile, String keystorePassword, String keystoreType, String keystoreAlias){
18 this.keystoreFile=keystoreFile;
19 this.keystorePassword=keystorePassword;
20 this.keystoreType=keystoreType;
21 this.keystoreAlias=keystoreAlias;
22 }
23
24 public void customize(Connector connector){
25 connector.setSecure(true);
26 connector.setScheme("https");
27 connector.setAttribute("keystoreFile", keystoreFile);
28 connector.setAttribute("keystorePass", keystorePassword);
29 connector.setAttribute("keystoreType", keystoreType);
30 connector.setAttribute("keyAlias", keystoreAlias);
31 connector.setAttribute("clientAuth", "false");
32 connector.setAttribute("sslProtocol", "TLS");
33 connector.setAttribute("SSLEnabled", true);
34 }
35 }
36
37 public class ESCC implements EmbeddedServletContainerCustomizer{
38 private String keystoreFile;
39 private String keystorePassword;
40 private String keystoreType;
41 private String keystoreAlias;
42
43 public ESCC(String keystoreFile, String keystorePassword, String keystoreType, String keystoreAlias){
44 this.keystoreFile=keystoreFile;
45 this.keystorePassword=keystorePassword;
46 this.keystoreType=keystoreType;
47 this.keystoreAlias=keystoreAlias;
48 }
49
50 public void customize(ConfigurableEmbeddedServletContainer container){
51 TomcatEmbeddedServletContainerFactory containerFactory = (TomcatEmbeddedServletContainerFactory) container;
52
53 TomcatConnectorCustomizer tcc = new TCC(keystoreFile,keystorePassword,keystoreType,keystoreAlias);
54 containerFactory.addConnectorCustomizers(tcc);
55 }
56 }
57
58 @Bean
59 @Inject
60 public EmbeddedServletContainerCustomizer containerCustomizer(
61 @Value("${keystore.file}") String keystoreFile,
62 @Value("${keystore.password}") String keystorePassword,
63 @Value("${keystore.type}") String keystoreType,
64 @Value("${keystore.alias}") String keystoreAlias) throws FileNotFoundException
65 {
66 final String absoluteKeystoreFile = ResourceUtils.getFile(keystoreFile).getAbsolutePath();
67 EmbeddedServletContainerCustomizer escc = new ESCC(absoluteKeystoreFile,keystorePassword,keystoreType,keystoreAlias);
68 return escc;
69 }
pom.xml
- 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
It's also possible to override values with environment variables as for example
- FOO_BAR=snafu java -jar target/test-spring-boot-0.1.0.jar
The *.* should be replaced by *_* and the lowercase characters must be capitalized.
Instead of using @Autowired or @Inject use @Resource (javax.annotation.Resource).
Example JPA RabbitMQ HttpSession Redis
Structure
. ./pom.xml ./src ./src/main ./src/main/java ./src/main/java/hello ./src/main/java/hello/GreetingController.java ./src/main/java/hello/Application.java ./src/main/java/hello/ThreadTimer.java ./src/main/java/hello/WaitThread.java ./src/main/java/hello/Dummy.java ./src/main/java/hello/DummyDAO.java ./src/main/java/hello/DummyJPA.java ./src/main/java/hello/MessageHandler.java ./src/main/java/hello/BroadcastMessageHandler.java ./src/main/java/hello/ConfigHttpSession.java ./src/main/resources ./src/main/resources/templates ./src/main/resources/templates/greeting.html ./src/main/resources/application.properties ./src/main/resources/logback-spring.xml ./src/main/resources/test.sql ./src/main/resources/META-INF ./src/main/resources/META-INF/persistence.xml
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 }
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 public ThreadTimer() {
20 this.logger = LoggerFactory.getLogger(ThreadTimer.class);
21 logger.info("Created instance of " + this.getClass().getSimpleName());
22 this.running = true;
23 this.delaySeconds = 5 * 1000;
24 this.setName(this.getClass().getSimpleName() + "_" + this.getName());
25 this.subscribers = new ArrayList<Object>();
26 }
27
28 public void addSubscriber(Object subscriber){
29 this.subscribers.add(subscriber);
30 }
31
32 @PostConstruct
33 public void init() {
34 logger.info("Starting the thread");
35 this.start();
36 }
37
38 @Override
39 public void run() {
40 while (running) {
41 try {
42 Thread.sleep(this.delaySeconds);
43 logger.info("Delay " + this.getClass().getSimpleName());
44
45 for(Object o: this.subscribers){
46 synchronized(o){
47 o.notify();
48 }
49 }
50 }
51 catch (InterruptedException e) {
52 logger.info("ThreadTimer interrupted exception:" + e.getMessage() );
53 }
54 catch (Exception e) {
55 e.printStackTrace();
56 logger.info("ThreadTimer exception:" + e.getMessage() );
57 stopRunning();
58 }
59 }
60 logger.info("Exited " + this.getClass().getSimpleName());
61 }
62
63 public void startRunning() {
64 this.running = true;
65 }
66
67 public void stopRunning() {
68 this.running = false;
69 }
70
71 public void destroy(){
72 logger.info("Called destroy");
73 this.stopRunning();
74 this.interrupt();
75 }
76 }
MessageHandler.java
1 package hello;
2
3 import java.nio.charset.StandardCharsets;
4 import org.slf4j.Logger;
5 import org.slf4j.LoggerFactory;
6
7 public class MessageHandler{
8 private final Logger logger = LoggerFactory.getLogger(MessageHandler.class);
9
10 public void handleMessage(byte[] message){
11 String msg = new String(message, StandardCharsets.UTF_8);
12 logger.info("Received msg " + msg );
13 }
14
15 public void handleMessage(String message){
16 logger.info("Received msg " + message );
17 }
18
19 }
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 import org.springframework.web.bind.annotation.PathVariable;
16 //import javax.inject.Inject;
17 import org.springframework.core.env.Environment;
18 import org.springframework.beans.factory.annotation.Value;
19 import javax.annotation.Resource;
20
21 import org.springframework.amqp.rabbit.core.RabbitTemplate;
22 import javax.servlet.http.HttpSession;
23
24 @Controller
25 public class GreetingController {
26 private final Logger logger = LoggerFactory.getLogger(GreetingController.class);
27 @Resource
28 DummyDAO dummyDAO;
29
30 @Resource
31 Environment env;
32
33 @Resource
34 RabbitTemplate rabbitTemplate;
35
36 @Value("${instance.name}")
37 String instanceName;
38
39 public GreetingController(){
40 logger.debug("Greeting controller created.");
41 }
42
43 @RequestMapping("/greeting")
44 public String greeting(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model ) {
45 model.addAttribute("name", name);
46 rabbitTemplate.convertAndSend("topicExchange","myQueue", name );
47 rabbitTemplate.convertAndSend("fanoutExchange","", name );
48 return "greeting";
49 }
50
51 @RequestMapping("/setvalue/{value}")
52 @ResponseBody
53 public String setValue(@PathVariable("value") String value, Model model,HttpSession httpSession) {
54 httpSession.setAttribute("name", value );
55 return httpSession.getId();
56 }
57
58 @RequestMapping("/getvalue")
59 @ResponseBody
60 public String setValue(Model model,HttpSession httpSession) {
61 return (String) httpSession.getAttribute("name");
62 }
63
64 @RequestMapping("/instancename")
65 @ResponseBody
66 public String setValue(Model model) {
67 return this.instanceName;
68 }
69
70 @RequestMapping("/greeting/add/{name}")
71 public String addGreeting(@PathVariable("name") String name, Model model) {
72 model.addAttribute("name", name);
73 dummyDAO.addName(name);
74 return "greeting";
75 }
76
77 @RequestMapping(value="/dummy",produces="application/json")
78 @ResponseBody
79 public List<DummyJPA> dummy(){
80 return dummyDAO.getAllNames();
81 }
82
83 @RequestMapping(value="/dummyname",produces="application/json")
84 @ResponseBody
85 public String getDummyName(){
86 return dummyDAO.getNameFromDummy();
87 }
88
89 @Value("${foo.bar}")
90 private String fooBar;
91
92 @RequestMapping(value="/env",produces="application/json")
93 @ResponseBody
94 public List<String> getEnv(){
95 List<String> ret = new ArrayList<String>();
96 ret.add( env.getProperty("foo.bar") );
97 ret.add(fooBar);
98 return ret;
99 }
100
101 }
DummyJPA.java
1 package hello;
2
3 import javax.persistence.Entity;
4 import javax.persistence.GeneratedValue;
5 import javax.persistence.GenerationType;
6 import javax.persistence.Id;
7 import javax.persistence.NamedQuery;
8 import javax.persistence.NamedQueries;
9
10 @Entity
11 @NamedQueries({
12 @NamedQuery(name="DummyJPA.getAll", query="Select e From DummyJPA e")
13 })
14 public class DummyJPA{
15 @Id
16 @GeneratedValue(strategy=GenerationType.AUTO)
17 private Long id;
18 private String dummy;
19
20 public DummyJPA(){
21 }
22
23 public String getDummy(){
24 return this.dummy;
25 }
26
27 public void setDummy(String dummy){
28 this.dummy=dummy;
29 }
30
31 @Override
32 public String toString(){
33 return String.format("Dummy %s", this.dummy);
34 }
35 }
DummyDAO.java
1 package hello;
2
3 import org.slf4j.Logger;
4 import org.slf4j.LoggerFactory;
5 import org.springframework.beans.factory.annotation.Autowired;
6 import org.springframework.beans.factory.annotation.Qualifier;
7 import org.springframework.jdbc.core.JdbcTemplate;
8 import org.springframework.stereotype.Component;
9 import javax.persistence.PersistenceContext;
10 import javax.persistence.EntityManager;
11 import javax.persistence.Query;
12 import javax.transaction.Transactional;
13 import java.util.List;
14
15 @Component
16 public class DummyDAO {
17 @Autowired
18 @Qualifier("jdbcTemplate")
19 private JdbcTemplate jdbcTemplate;
20 private Logger logger;
21
22 @PersistenceContext(unitName="default")
23 EntityManager em;
24
25 public DummyDAO() {
26 logger = LoggerFactory.getLogger(DummyDAO.class);
27 logger.info("Created " + this.getClass().getSimpleName());
28 }
29
30 public String getNameFromDummy() {
31 return this.jdbcTemplate.queryForObject("select name from dummy limit 1", String.class);
32 }
33
34 @Transactional
35 public void addName(String name){
36 DummyJPA djpa = new DummyJPA();
37 djpa.setDummy(name);
38 em.persist(djpa);
39 }
40
41 @Transactional
42 public List<DummyJPA> getAllNames(){
43 return em.createNamedQuery("DummyJPA.getAll",DummyJPA.class).getResultList();
44 }
45
46 }
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 }
ConfigHttpSession.java
1 /*
2 http://docs.spring.io/spring-session/docs/current/reference/html5/guides/boot.html
3
4 pkg install redis #freebsd
5 add redis_enable="YES" to /etc/rc.conf
6 /usr/local/etc/rc.d/redis start
7
8 /usr/local/etc/redis.conf
9 requirepass 12345678
10
11 keys *
12 hgetall <hashkey>
13
14 Same as in application.properties spring.redis.password=12345678
15
16 https://localhost:8443/setvalue/valx
17 147569e4-9e6d-4363-a373-b20261513f11
18
19 https://localhost:8443/getvalue
20 SESSION=147569e4-9e6d-4363-a373-b20261513f11
21
22 2 instances of spring boot using the same redis server
23 curl -k -v --cookie "SESSION=147569e4-9e6d-4363-a373-b20261513f11" https://localhost:8443/getvalue
24 curl -k -v --cookie "SESSION=147569e4-9e6d-4363-a373-b20261513f11" https://localhost:8444/getvalue
25 */
26 package hello;
27
28 import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
29
30 @EnableRedisHttpSession
31 public class ConfigHttpSession{
32 // springSessionRepositoryFilterbean is responsible for replacing the HttpSession with a custom implementation that is backed by Spring Session.
33 }
1 package hello;
2
3 import java.nio.charset.StandardCharsets;
4 import org.slf4j.Logger;
5 import org.slf4j.LoggerFactory;
6
7 public class BroadcastMessageHandler{
8 private final Logger logger = LoggerFactory.getLogger(BroadcastMessageHandler.class);
9
10 public void handleMessage(byte[] message){
11 String msg = new String(message, StandardCharsets.UTF_8);
12 logger.info("Received msg " + msg );
13 }
14
15 public void handleMessage(String message){
16 logger.info("Received msg " + message );
17 }
18 }
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 import org.apache.commons.dbcp.BasicDataSource;
10 import org.springframework.jdbc.core.JdbcTemplate;
11 import org.slf4j.Logger;
12 import org.slf4j.LoggerFactory;
13 import org.springframework.boot.autoconfigure.domain.EntityScan;
14 import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
15 import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
16 import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
17 import org.springframework.boot.context.embedded.tomcat.TomcatConnectorCustomizer;
18 import java.io.FileNotFoundException;
19 import org.apache.catalina.connector.Connector;
20 import org.springframework.beans.factory.annotation.Value;
21 import javax.inject.Inject;
22 import javax.annotation.Resource;
23 import org.springframework.util.ResourceUtils;
24 import org.springframework.core.env.Environment;
25
26 //-- rabbit
27 import org.springframework.amqp.core.Binding;
28 import org.springframework.amqp.core.BindingBuilder;
29 import org.springframework.amqp.core.Queue;
30 import org.springframework.amqp.core.TopicExchange;
31 import org.springframework.amqp.core.FanoutExchange;
32 import org.springframework.amqp.core.AnonymousQueue;
33 import org.springframework.amqp.rabbit.connection.ConnectionFactory;
34 import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;
35 import org.springframework.amqp.rabbit.listener.adapter.MessageListenerAdapter;
36 import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
37 import java.net.URI;
38 //-- rabbit
39
40 @ComponentScan
41 @EnableAutoConfiguration
42 @EntityScan(basePackages="hello")
43 public class Application {
44 @Resource
45 Environment env;
46
47 private static Logger logger;
48
49 public static void main(String[] args) {
50 logger = LoggerFactory.getLogger(Application.class);
51 logger.info("Starting application");
52 SpringApplication.run(Application.class, args);
53 }
54
55 @Bean(name="basicDataSource",destroyMethod="close")
56 public BasicDataSource createBasicDataSource(){
57 logger.info("Creating basicDataSource");
58 BasicDataSource bds = new BasicDataSource();
59 // get config data from application.properties
60 bds.setDriverClassName(env.getProperty("db.driverclass") );
61 bds.setUrl(env.getProperty("db.jdbcurl") );
62 bds.setUsername( env.getProperty("db.username") );
63 bds.setPassword( env.getProperty("db.password") );
64 bds.setInitialSize( Integer.parseInt( env.getProperty("db.initialsizeconnpool")) );
65 return bds;
66 }
67
68 @Bean(name="jdbcTemplate")
69 public JdbcTemplate createJdbcTemplate(@Autowired @Qualifier("basicDataSource") BasicDataSource bds ){
70 logger.info("Creating jdbcTemplate");
71 return new JdbcTemplate( bds );
72 }
73
74 //---
75 public class TCC implements TomcatConnectorCustomizer{
76 Environment env;
77
78 public TCC(Environment env){
79 this.env=env;
80 }
81
82 public void customize(Connector connector){
83 String absoluteKeystoreFile = "";
84 logger.info(String.format("Keystore file: %s" , env.getProperty("keystore.file") ));
85
86 try{
87 absoluteKeystoreFile = ResourceUtils.getFile(env.getProperty("keystore.file")).getAbsolutePath();
88 logger.info(String.format("Absolute path keystore: %s" , absoluteKeystoreFile ) );
89 }
90 catch(Exception ex){
91 logger.error( ex.getMessage() );
92 }
93
94 connector.setSecure(true);
95 connector.setScheme("https");
96 connector.setAttribute("keystoreFile", absoluteKeystoreFile);
97 connector.setAttribute("keystorePass", env.getProperty("keystore.password"));
98 connector.setAttribute("keystoreType", env.getProperty("keystore.type"));
99 connector.setAttribute("keyAlias", env.getProperty("keystore.alias") );
100 connector.setAttribute("clientAuth", "false");
101 connector.setAttribute("sslProtocol", "TLS");
102 connector.setAttribute("SSLEnabled", true);
103 }
104 }
105
106 public class ESCC implements EmbeddedServletContainerCustomizer{
107 Environment env;
108
109 public ESCC(Environment env){
110 this.env=env;
111 }
112
113 public void customize(ConfigurableEmbeddedServletContainer container){
114 TomcatEmbeddedServletContainerFactory containerFactory = (TomcatEmbeddedServletContainerFactory) container;
115 TomcatConnectorCustomizer tcc = new TCC(env);
116 containerFactory.addConnectorCustomizers(tcc);
117 }
118 }
119
120 @Bean(name="containerCustomizer")
121 public EmbeddedServletContainerCustomizer containerCustomizer()
122 throws FileNotFoundException {
123 logger.info("Creating containerCustomizer");
124 EmbeddedServletContainerCustomizer escc = new ESCC(env);
125 return escc;
126 }
127 //---
128
129 //---- rabbit
130
131 //import org.springframework.amqp.rabbit.connection.CachingConnectionFactory;
132 @Bean(name="cachingConnectionFactory")
133 CachingConnectionFactory createCachingConnectionFactory(){
134 logger.info("Creating cachingConnectionFactory");
135 String uri = env.getProperty("rabbitmq.uri");
136 URI rabbitmqUri=null;
137
138 try{
139 rabbitmqUri = new URI(uri);
140 }
141 catch(Exception ex){
142 ex.printStackTrace();
143 }
144
145 CachingConnectionFactory ret = new CachingConnectionFactory(rabbitmqUri);
146 logger.info(String.format("Created cachingConnectionFactory with hashCode %d" , ret.hashCode() ) );
147 return ret;
148 }
149
150 @Bean(name="myQueue")
151 Queue createMyQueue() {
152 logger.info("Creating myQueue");
153 return new Queue("myQueue", false);
154 }
155
156 @Bean(name="topicExchange")
157 TopicExchange createTopicExchange() {
158 logger.info("Creating topicExchange");
159 return new TopicExchange("topicExchange");
160 }
161
162 @Bean(name="bindingQueue")
163 Binding binding(@Qualifier("myQueue")Queue queue, @Qualifier("topicExchange")TopicExchange exchange) {
164 logger.info("Creating bindingQueue");
165 return BindingBuilder.bind(queue).to(exchange).with(queue.getName());
166 }
167
168 @Bean(name="workQueueContainer")
169 SimpleMessageListenerContainer createWorkQueueContainer(ConnectionFactory connectionFactory, @Autowired @Qualifier("listenerAdapter") MessageListenerAdapter listenerAdapter,@Qualifier("myQueue") Queue queue) {
170 logger.info("Creating createWorkQueueContainer for work queue");
171 logger.info(String.format("Using ConnectionFactory with hashCode %d" , connectionFactory.hashCode() ) );
172
173 SimpleMessageListenerContainer smlc = new SimpleMessageListenerContainer();
174 smlc.setConnectionFactory(connectionFactory);
175 smlc.setQueueNames(queue.getName() );
176 smlc.setMessageListener(listenerAdapter);
177 return smlc;
178 }
179
180 @Bean(name="listenerAdapter")
181 MessageListenerAdapter listenerAdapter(@Autowired @Qualifier("messageHandler")MessageHandler messageHandler) {
182 logger.info("Creating listenerAdapter");
183 return new MessageListenerAdapter(messageHandler);
184 }
185
186 @Bean(name="messageHandler")
187 MessageHandler createMessageHandler() {
188 logger.info("Creating messageHandler");
189 return new MessageHandler();
190 }
191
192 //--------
193 @Bean(name="fanoutExchange")
194 FanoutExchange createFanoutExchange() {
195 logger.info("Creating fanoutExchange");
196 return new FanoutExchange("fanoutExchange");
197 }
198
199 @Bean(name="anonymousQueue1")
200 AnonymousQueue createAnonymousQueue1() {
201 logger.info("Creating anonQueue1");
202 return new AnonymousQueue();
203 }
204
205 @Bean(name="bindingTopic")
206 Binding bindingTopic(@Qualifier("anonymousQueue1")AnonymousQueue queue, @Qualifier("fanoutExchange")FanoutExchange exchange) {
207 logger.info("Creating bindingTopic");
208 return BindingBuilder.bind(queue).to(exchange);
209 }
210
211 @Bean(name="broadcastMessageHandler")
212 BroadcastMessageHandler createBroadcastMessageHandler() {
213 logger.info("Creating broadcastMessageHandlermessageHandler");
214 return new BroadcastMessageHandler();
215 }
216
217 @Bean(name="broadcastListenerAdapter")
218 MessageListenerAdapter createBroadcastlistenerAdapter(@Autowired @Qualifier("broadcastMessageHandler")BroadcastMessageHandler broadcastMessageHandler) {
219 logger.info("Creating broadcastListenerAdapter");
220 return new MessageListenerAdapter(broadcastMessageHandler);
221 }
222
223 @Bean(name="topicContainer")
224 SimpleMessageListenerContainer createTopicContainer(ConnectionFactory connectionFactory, @Autowired @Qualifier("broadcastListenerAdapter") MessageListenerAdapter listenerAdapter, @Qualifier("anonymousQueue1") AnonymousQueue anonQueue) {
225 logger.info("Creating container for topic");
226 logger.info(String.format("Using ConnectionFactory with hashCode %d" , connectionFactory.hashCode() ) );
227
228 SimpleMessageListenerContainer smlc = new SimpleMessageListenerContainer();
229 smlc.setConnectionFactory(connectionFactory);
230 smlc.setQueueNames( anonQueue.getName() );
231 smlc.setMessageListener(listenerAdapter);
232 return smlc;
233 }
234
235 //----
236 //---- rabbit
237 }
persistence.xml
1 <persistence>
2 <persistence-unit name="default" transaction-type="RESOURCE_LOCAL">
3 <jta-data-source>basicDataSource</jta-data-source>
4 <properties>
5 <!-- <property name="hibernate.hbm2ddl.auto" value="create-drop" /> -->
6 <property name="hibernate.hbm2ddl.auto" value="update" />
7 <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
8 <property name="hibernate.show_sql" value="false" />
9 </properties>
10 </persistence-unit>
11 </persistence>
greeting.html
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
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>
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
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 <dependency>
29 <groupId>org.springframework</groupId>
30 <artifactId>spring-jdbc</artifactId>
31 <version>4.3.2.RELEASE</version>
32 </dependency>
33 <dependency>
34 <groupId>org.springframework.boot</groupId>
35 <artifactId>spring-boot-starter-data-jpa</artifactId>
36 </dependency>
37 <dependency>
38 <groupId>org.springframework.boot</groupId>
39 <artifactId>spring-boot-starter-amqp</artifactId>
40 </dependency>
41 <dependency>
42 <groupId>javax.inject</groupId>
43 <artifactId>javax.inject</artifactId>
44 <version>1</version>
45 </dependency>
46 <!-- http session redis -->
47 <dependency>
48 <groupId>org.springframework.session</groupId>
49 <artifactId>spring-session</artifactId>
50 <version>1.2.2.RELEASE</version>
51 </dependency>
52 <dependency>
53 <groupId>org.springframework.boot</groupId>
54 <artifactId>spring-boot-starter-data-redis</artifactId>
55 </dependency>
56 <!-- http session redis -->
57 </dependencies>
58 <properties>
59 <start-class>hello.Application</start-class>
60 </properties>
61 <build>
62 <plugins>
63 <plugin>
64 <groupId>org.springframework.boot</groupId>
65 <artifactId>spring-boot-maven-plugin</artifactId>
66 </plugin>
67 </plugins>
68 </build>
69 <repositories>
70 <repository>
71 <id>spring-milestone</id>
72 <url>http://repo.spring.io/libs-release</url>
73 </repository>
74 </repositories>
75 <pluginRepositories>
76 <pluginRepository>
77 <id>spring-milestone</id>
78 <url>http://repo.spring.io/libs-release</url>
79 </pluginRepository>
80 </pluginRepositories>
81 </project>
Libs
1 -rw-r--r-- 1 vitor vitor 37M Sep 29 15:49 test-spring-boot-0.1.0.jar
2 jar tf test-spring-boot-0.1.0.jar | grep BOOT | grep jar
3 BOOT-INF/lib/spring-session-1.2.2.RELEASE.jar
4 BOOT-INF/lib/spring-boot-starter-data-redis-1.4.0.RELEASE.jar
5 BOOT-INF/lib/jackson-core-2.8.1.jar
6 BOOT-INF/lib/javassist-3.20.0-GA.jar
7 BOOT-INF/lib/jul-to-slf4j-1.7.21.jar
8 BOOT-INF/lib/groovy-2.4.7.jar
9 BOOT-INF/lib/spring-amqp-1.6.1.RELEASE.jar
10 BOOT-INF/lib/hibernate-validator-5.2.4.Final.jar
11 BOOT-INF/lib/classmate-1.3.1.jar
12 BOOT-INF/lib/hibernate-commons-annotations-5.0.1.Final.jar
13 BOOT-INF/lib/tomcat-embed-el-8.5.4.jar
14 BOOT-INF/lib/jedis-2.8.2.jar
15 BOOT-INF/lib/httpcore-4.4.5.jar
16 BOOT-INF/lib/antlr-2.7.7.jar
17 BOOT-INF/lib/xml-apis-1.4.01.jar
18 BOOT-INF/lib/spring-boot-starter-tomcat-1.4.0.RELEASE.jar
19 BOOT-INF/lib/thymeleaf-layout-dialect-1.4.0.jar
20 BOOT-INF/lib/spring-boot-autoconfigure-1.4.0.RELEASE.jar
21 BOOT-INF/lib/snakeyaml-1.17.jar
22 BOOT-INF/lib/http-client-1.0.0.RELEASE.jar
23 BOOT-INF/lib/httpclient-4.5.2.jar
24 BOOT-INF/lib/spring-boot-starter-logging-1.4.0.RELEASE.jar
25 BOOT-INF/lib/tomcat-jdbc-8.5.4.jar
26 BOOT-INF/lib/spring-beans-4.3.2.RELEASE.jar
27 BOOT-INF/lib/spring-jdbc-4.3.2.RELEASE.jar
28 BOOT-INF/lib/spring-boot-starter-jdbc-1.4.0.RELEASE.jar
29 BOOT-INF/lib/spring-boot-starter-amqp-1.4.0.RELEASE.jar
30 BOOT-INF/lib/spring-aspects-4.3.2.RELEASE.jar
31 BOOT-INF/lib/commons-dbcp-1.4.jar
32 BOOT-INF/lib/spring-data-commons-1.12.2.RELEASE.jar
33 BOOT-INF/lib/spring-context-support-4.3.2.RELEASE.jar
34 BOOT-INF/lib/spring-data-keyvalue-1.1.2.RELEASE.jar
35 BOOT-INF/lib/spring-boot-starter-1.4.0.RELEASE.jar
36 BOOT-INF/lib/tomcat-embed-websocket-8.5.4.jar
37 BOOT-INF/lib/commons-logging-1.2.jar
38 BOOT-INF/lib/spring-tx-4.3.2.RELEASE.jar
39 BOOT-INF/lib/validation-api-1.1.0.Final.jar
40 BOOT-INF/lib/spring-core-4.3.2.RELEASE.jar
41 BOOT-INF/lib/spring-boot-starter-aop-1.4.0.RELEASE.jar
42 BOOT-INF/lib/spring-data-jpa-1.10.2.RELEASE.jar
43 BOOT-INF/lib/commons-pool2-2.4.2.jar
44 BOOT-INF/lib/dom4j-1.6.1.jar
45 BOOT-INF/lib/tomcat-juli-8.5.4.jar
46 BOOT-INF/lib/jcl-over-slf4j-1.7.21.jar
47 BOOT-INF/lib/log4j-over-slf4j-1.7.21.jar
48 BOOT-INF/lib/aspectjweaver-1.8.9.jar
49 BOOT-INF/lib/spring-data-redis-1.7.2.RELEASE.jar
50 BOOT-INF/lib/spring-web-4.3.2.RELEASE.jar
51 BOOT-INF/lib/unbescape-1.1.0.RELEASE.jar
52 BOOT-INF/lib/mariadb-java-client-1.4.4.jar
53 BOOT-INF/lib/amqp-client-3.6.3.jar
54 BOOT-INF/lib/spring-oxm-4.3.2.RELEASE.jar
55 BOOT-INF/lib/tomcat-embed-core-8.5.4.jar
56 BOOT-INF/lib/spring-orm-4.3.2.RELEASE.jar
57 BOOT-INF/lib/hibernate-jpa-2.1-api-1.0.0.Final.jar
58 BOOT-INF/lib/commons-pool-1.6.jar
59 BOOT-INF/lib/thymeleaf-spring4-2.1.5.RELEASE.jar
60 BOOT-INF/lib/hibernate-core-5.0.9.Final.jar
61 BOOT-INF/lib/spring-context-4.3.2.RELEASE.jar
62 BOOT-INF/lib/thymeleaf-2.1.5.RELEASE.jar
63 BOOT-INF/lib/commons-codec-1.10.jar
64 BOOT-INF/lib/spring-boot-starter-web-1.4.0.RELEASE.jar
65 BOOT-INF/lib/spring-webmvc-4.3.2.RELEASE.jar
66 BOOT-INF/lib/slf4j-api-1.7.21.jar
67 BOOT-INF/lib/javax.inject-1.jar
68 BOOT-INF/lib/jackson-annotations-2.8.1.jar
69 BOOT-INF/lib/jandex-2.0.0.Final.jar
70 BOOT-INF/lib/spring-messaging-4.3.2.RELEASE.jar
71 BOOT-INF/lib/ognl-3.0.8.jar
72 BOOT-INF/lib/hibernate-entitymanager-5.0.9.Final.jar
73 BOOT-INF/lib/spring-boot-starter-thymeleaf-1.4.0.RELEASE.jar
74 BOOT-INF/lib/spring-retry-1.1.3.RELEASE.jar
75 BOOT-INF/lib/javax.transaction-api-1.2.jar
76 BOOT-INF/lib/logback-classic-1.1.7.jar
77 BOOT-INF/lib/spring-boot-starter-data-jpa-1.4.0.RELEASE.jar
78 BOOT-INF/lib/spring-boot-1.4.0.RELEASE.jar
79 BOOT-INF/lib/spring-expression-4.3.2.RELEASE.jar
80 BOOT-INF/lib/logback-core-1.1.7.jar
81 BOOT-INF/lib/jackson-databind-2.8.1.jar
82 BOOT-INF/lib/spring-rabbit-1.6.1.RELEASE.jar
83 BOOT-INF/lib/spring-aop-4.3.2.RELEASE.jar
84 BOOT-INF/lib/jboss-logging-3.3.0.Final.jar
springTestApp
pom.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
5 http://maven.apache.org/xsd/maven-4.0.0.xsd">
6 <modelVersion>4.0.0</modelVersion>
7 <groupId>org.allowed.bitarus</groupId>
8 <artifactId>springTestApp</artifactId>
9 <version>0.1.0</version>
10 <parent>
11 <groupId>org.springframework.boot</groupId>
12 <artifactId>spring-boot-starter-parent</artifactId>
13 <version>1.4.2.RELEASE</version>
14 </parent>
15 <dependencies>
16 <dependency>
17 <groupId>org.springframework.boot</groupId>
18 <artifactId>spring-boot-starter-web</artifactId>
19 </dependency>
20 </dependencies>
21 <properties>
22 <start-class>org.allowed.bitarus.springTestApp.Application</start-class>
23 </properties>
24 <build>
25 <plugins>
26 <plugin>
27 <artifactId>maven-compiler-plugin</artifactId>
28 <version>2.3.2</version>
29 </plugin>
30 <plugin>
31 <groupId>org.springframework.boot</groupId>
32 <artifactId>spring-boot-maven-plugin</artifactId>
33 </plugin>
34 </plugins>
35 </build>
36 <repositories>
37 <repository>
38 <id>spring-releases</id>
39 <url>http://repo.spring.io/libs-release</url>
40 </repository>
41 </repositories>
42 <pluginRepositories>
43 <pluginRepository>
44 <id>spring-releases</id>
45 <url>http://repo.spring.io/libs-release</url>
46 </pluginRepository>
47 </pluginRepositories>
48 </project>
src/main/java/org/allowed/bitarus/springTestApp/Application.java
1 package org.allowed.bitarus.springTestApp;
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.boot.autoconfigure.SpringBootApplication;
7 import org.springframework.context.annotation.Bean;
8 import java.util.concurrent.Future;
9 import java.util.ArrayList;
10 import java.util.concurrent.ExecutorService;
11 import java.util.concurrent.Executors;
12
13 @ComponentScan
14 @EnableAutoConfiguration
15 @SpringBootApplication
16 public class Application {
17
18 public static void main(String[] args) {
19 SpringApplication.run(Application.class, args);
20 }
21
22 @Bean(name="tasksFutures")
23 public ArrayList<Future<Integer>> createTasksFutures(){
24 System.out.println("Creating tasksFutures");
25 return new ArrayList<Future<Integer>>();
26 }
27
28 @Bean(name="executors")
29 public ExecutorService createExecutors(){
30 return Executors.newFixedThreadPool(5);
31 }
32 }
src/main/java/org/allowed/bitarus/springTestApp/Tasker.java
1 package org.allowed.bitarus.springTestApp;
2
3 import org.springframework.stereotype.Component;
4 import java.util.concurrent.ExecutorService;
5 import java.util.concurrent.Future;
6 import org.springframework.beans.factory.annotation.Autowired;
7 import org.springframework.beans.factory.annotation.Qualifier;
8
9 @Component("tasker")
10 public class Tasker {
11 private ExecutorService _es;
12
13 public Tasker(@Qualifier("executors") ExecutorService es){
14 System.out.println("Created Tasker !!!!");
15 _es = es;
16 }
17
18 public Future<Integer> addTask(TaskX taskx){
19 Future<Integer> f = _es.submit( taskx );
20 return f;
21 }
22 }
src/main/java/org/allowed/bitarus/springTestApp/Receiver.java
1 package org.allowed.bitarus.springTestApp;
2
3 import org.springframework.stereotype.Component;
4 import java.util.concurrent.Future;
5 import java.util.ArrayList;
6 import org.springframework.beans.factory.annotation.Qualifier;
7 import javax.annotation.PostConstruct;
8
9 @Component
10 public class Receiver {
11 private Tasker _t;
12 private ArrayList<Future<Integer>> _tasks;
13
14 public Receiver(@Qualifier("tasker")Tasker t, @Qualifier("tasksFutures") ArrayList<Future<Integer>> tasks ){
15 System.out.println("Created receiver !!!!");
16 _t = t;
17 _tasks = tasks;
18 // wait for all tasks ...
19 /*
20 boolean loop=true;
21 while(loop){
22 boolean allDone=true;
23 for(Future<Integer> f : tasks){
24 if(f.isDone()==false){
25 allDone=false;
26 }
27 }
28
29 if(allDone){
30 loop=false;
31 }
32
33 try{
34 Thread.sleep(1000);
35 }
36 catch(Exception ex){
37 }
38 }
39
40 for(Future<Integer> f : tasks){
41 try{
42 Integer res = f.get();
43 System.out.println(res);
44 }
45 catch(Exception ex){
46 }
47 } */
48 }
49
50 @PostConstruct
51 public void init(){
52 System.out.println("Init post construct");
53 for(int i=0;i<10;i++){
54 _tasks.add( _t.addTask( new TaskX(5,6) ) );
55 }
56 }
57 }
TaskX.java
1 package org.allowed.bitarus.springTestApp;
2
3 import java.util.concurrent.Callable;
4
5 public class TaskX implements Callable<Integer>{
6 private int _x;
7 private int _y;
8
9 public TaskX(int x,int y){
10 _x=x;
11 _y=y;
12 }
13
14 public Integer call() {
15 try {
16 Thread.sleep(5000);
17 }
18 catch(Exception ex){
19 }
20 int sum = _x+_y;
21 System.out.println("TID:"+Thread.currentThread().getId() + " sumVal:" + sum );
22 return sum;
23 }
24 }
Example with MongoDB
Think about using spring.data.mongodb.uri.
pom.xml
1 <?xml version="1.0" encoding="UTF-8"?>
2 <project xmlns="http://maven.apache.org/POM/4.0.0"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
5 http://maven.apache.org/xsd/maven-4.0.0.xsd">
6 <modelVersion>4.0.0</modelVersion>
7 <groupId>org.allowed.bitarus</groupId>
8 <artifactId>springTestApp</artifactId>
9 <version>0.1.0</version>
10 <parent>
11 <groupId>org.springframework.boot</groupId>
12 <artifactId>spring-boot-starter-parent</artifactId>
13 <version>1.4.2.RELEASE</version>
14 </parent>
15 <dependencies>
16 <dependency>
17 <groupId>org.springframework.boot</groupId>
18 <artifactId>spring-boot-starter-web</artifactId>
19 </dependency>
20 <dependency>
21 <groupId>org.springframework.data</groupId>
22 <artifactId>spring-data-mongodb</artifactId>
23 <version>1.9.6.RELEASE</version>
24 </dependency>
25 </dependencies>
26 <properties>
27 <start-class>org.allowed.bitarus.springTestApp.Application</start-class>
28 </properties>
29 <build>
30 <plugins>
31 <plugin>
32 <artifactId>maven-compiler-plugin</artifactId>
33 <version>2.3.2</version>
34 </plugin>
35 <plugin>
36 <groupId>org.springframework.boot</groupId>
37 <artifactId>spring-boot-maven-plugin</artifactId>
38 </plugin>
39 </plugins>
40 </build>
41 <repositories>
42 <repository>
43 <id>spring-releases</id>
44 <url>http://repo.spring.io/libs-release</url>
45 </repository>
46 </repositories>
47 <pluginRepositories>
48 <pluginRepository>
49 <id>spring-releases</id>
50 <url>http://repo.spring.io/libs-release</url>
51 </pluginRepository>
52 </pluginRepositories>
53 </project>
src/main/resources/application.properties
src/main/java/org/allowed/bitarus/springTestApp/Application.java
1 package org.allowed.bitarus.springTestApp;
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.boot.autoconfigure.SpringBootApplication;
7 import org.springframework.context.annotation.Bean;
8 import java.util.concurrent.Future;
9 import java.util.ArrayList;
10 import java.util.concurrent.ExecutorService;
11 import java.util.concurrent.Executors;
12 import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
13 import org.springframework.data.mongodb.core.MongoTemplate;
14 import com.mongodb.Mongo;
15 import org.springframework.core.env.Environment;
16 import javax.annotation.Resource;
17
18 @ComponentScan
19 @EnableAutoConfiguration
20 @SpringBootApplication
21 @EnableMongoRepositories // search for MongoDB reps
22 public class Application {
23 @Resource
24 Environment _env;
25
26 public static void main(String[] args) {
27 SpringApplication.run(Application.class, args);
28 }
29
30 @Bean(name="tasksFutures")
31 public ArrayList<Future<Integer>> createTasksFutures(){
32 System.out.println("Creating tasksFutures");
33 return new ArrayList<Future<Integer>>();
34 }
35
36 @Bean(name="executors")
37 public ExecutorService createExecutors(){
38 System.out.println("Creating executors");
39 System.out.println(_env.getProperty("threadpool.nrExecutors"));
40 return Executors.newFixedThreadPool(5);
41 }
42
43 @Bean(name="mongoTemplate")
44 public MongoTemplate mongoTemplate() throws Exception {
45 System.out.println("Creating mongoTemplate");
46 System.out.println(_env.getProperty("mongox.host"));
47 System.out.println(_env.getProperty("mongox.port"));
48 System.out.println(_env.getProperty("mongox.database"));
49 Mongo mongo = new Mongo( _env.getProperty("mongox.host"), Integer.parseInt(_env.getProperty("mongox.port") ) );
50 return new MongoTemplate(mongo, _env.getProperty("mongox.database") );
51 }
52 }
src/main/java/org/allowed/bitarus/springTestApp/Tasker.java
1 package org.allowed.bitarus.springTestApp;
2
3 import org.springframework.stereotype.Component;
4 import java.util.concurrent.ExecutorService;
5 import java.util.concurrent.Future;
6 import org.springframework.beans.factory.annotation.Autowired;
7 import org.springframework.beans.factory.annotation.Qualifier;
8
9 @Component("tasker")
10 public class Tasker {
11 private ExecutorService _es;
12
13 public Tasker(@Qualifier("executors") ExecutorService es){
14 System.out.println("Created Tasker !!!!");
15 _es = es;
16 }
17
18 public Future<Integer> addTask(TaskX taskx){
19 Future<Integer> f = _es.submit( taskx );
20 return f;
21 }
22 }
src/main/java/org/allowed/bitarus/springTestApp/Result.java
1 package org.allowed.bitarus.springTestApp;
2
3 import org.springframework.data.annotation.Id;
4
5 public class Result {
6 @Id
7 private String id;
8 private int sumResult;
9
10 public Result(){}
11 public int getSumResult(){return this.sumResult;}
12 public void setSumResult(int sumResult){this.sumResult=sumResult;}
13 public String getId(){return this.id;}
14 public void setId(String id){this.id=id;}
15 }
src/main/java/org/allowed/bitarus/springTestApp/Receiver.java
1 package org.allowed.bitarus.springTestApp;
2
3 import org.springframework.stereotype.Component;
4 import java.util.concurrent.Future;
5 import java.util.ArrayList;
6 import java.util.List;
7 import org.springframework.beans.factory.annotation.Qualifier;
8 import javax.annotation.PostConstruct;
9 import org.springframework.beans.factory.annotation.Autowired;
10 import org.springframework.data.mongodb.core.query.Query;
11 import org.springframework.data.mongodb.core.MongoTemplate;
12
13 @Component
14 public class Receiver {
15 private Tasker _t;
16 private ArrayList<Future<Integer>> _tasks;
17 private ResultRepository _repository;
18
19 public Receiver(@Qualifier("tasker")Tasker t, @Qualifier("tasksFutures") ArrayList<Future<Integer>> tasks, ResultRepository repository ){
20 System.out.println("Created receiver !!!!");
21 _t = t;
22 _tasks = tasks;
23 _repository = repository;
24 }
25 @Autowired
26 private MongoTemplate mongoTemplate;
27
28 @PostConstruct
29 public void init(){
30 System.out.println("Init post construct");
31 for(int i=0;i<10;i++){
32 _tasks.add( _t.addTask( new TaskX(5,6) ) );
33 }
34
35 // wait for all tasks ...
36 boolean loop=true;
37 while(loop){
38 boolean allDone=true;
39 for(Future<Integer> f : _tasks){
40 if(f.isDone()==false){
41 allDone=false;
42 }
43 }
44
45 if(allDone){
46 loop=false;
47 }
48
49 try{
50 Thread.sleep(1000);
51 }
52 catch(Exception ex){
53 }
54 }
55
56 for(Future<Integer> f : _tasks){
57 try{
58 Integer res = f.get();
59 System.out.println(res);
60 Result r = new Result();
61 r.setSumResult(res);
62 _repository.save(r);
63 }
64 catch(Exception ex){
65 }
66 }
67
68 System.out.println( _repository.count() );
69 List<Result> res = _repository.findBySumResult(11);
70 for(Result r : res){
71 r.setSumResult((int)System.currentTimeMillis());
72 _repository.save(r);
73 }
74
75 System.out.println("mongoTemplateCount " + mongoTemplate.count(new Query() ,Result.class) );
76 }
77 }
src/main/java/org/allowed/bitarus/springTestApp/ResultRepository.java
1 package org.allowed.bitarus.springTestApp;
2
3 import java.util.List;
4 import org.springframework.data.mongodb.repository.MongoRepository;
5 /*
6 Result -> class to store
7 String -> id in collection type
8 Collection result in database mydatabase
9 { "_id" : ObjectId("58828e2822e1a609d96a5e52"), "_class" : "org.allowed.bitarus.springTestApp.Result", "sumResult" : 11 }
10 */
11 public interface ResultRepository extends MongoRepository<Result, String> {
12 public List<Result> findBySumResult(int sumResult);
13 }
src/main/java/org/allowed/bitarus/springTestApp/TaskX.java
1 package org.allowed.bitarus.springTestApp;
2
3 import java.util.concurrent.Callable;
4
5 public class TaskX implements Callable<Integer>{
6 private int _x;
7 private int _y;
8
9 public TaskX(int x,int y){
10 _x=x;
11 _y=y;
12 }
13
14 public Integer call() {
15 try {
16 Thread.sleep(5000);
17 }
18 catch(Exception ex){
19 }
20 int sum = _x+_y;
21 System.out.println("TID:"+Thread.currentThread().getId() + " sumVal:" + sum );
22
23 return sum;
24 }
25 }