"4S"框架是我爲了區別傳統的SSH和SSM說法,提出的一個叫法。自從有了Spring MVC,特別是Spring Boot後,Java服務已經從臃腫的配置中解放出來。Java 服務也能夠知足快速構建的須要,迭代速度上並不比PHP,NodeJS差什麼。可是不少公司的Java技術棧過於陳舊,沒法發揮Java的現有優點。本文主要闡述如何快速優雅的構建一個完整的Java工程。本文提供4S框架的工程化方案。javascript
內容包括:html
本文意圖:前端
以上就是Java服務中最多見的框架思路。這3個最多見的框架之間涉及到框架的整合,並且框架自己的使用也涉及到大量的配置,如MyBatis的Mapping文件。若是能去掉這些框架整合的部分,固然不光是這三個框架的整合,實際業務還包括緩存,消息中間件等大量框架的整合,會十分的美好。若是再優化下ORM映射的過程,會更加的美好。因而有了"4S"。java
推薦IntelliJ IDEA構建Spring Boot項目。動手點一點,三步搞定一個Spring Boot的Maven工程,就問你簡單不簡單?
mysql
搞定後,找到包的根目錄下的Application文件,運行main函數,一個Java服務就啓動了,連Tomcat都不用配置。web
提供一種基於4S框架的分包思路,供參考。spring
開發環境和測試環境鏈接的數據庫和一些配置信息不一樣,能夠經過在application.properties指定不一樣的配置文件sql
# 配置環境 正式環境release 開發環境debug
spring.profiles.active=debug複製代碼
而後在application-debug.properties中配置測試環境信息,在application-release.properties中配置正式環境信息。數據庫
日誌配置很簡單,在application.properties作點配置便可,列舉幾條經常使用的緩存
# 日誌地址
logging.file=D:/springBoot/log.log
# 日誌打印級別
logging.level.org.springframework.web=DEBUG複製代碼
/value/JavaBean 和 /resource/value/xxx.properties 創建一一對應的關係。能夠經過Bean對象獲取xxx.properties中的常量信息。舉個例子。
/resource/value/user.properties
user.name=wolearn
user.age=12複製代碼
/java/包名/value/UserProperty.java
@Component
@ConfigurationProperties(prefix = "user", ignoreUnknownFields = false)
@PropertySource("classpath:/value/user.properties")
public class UserProperty {
private String name;
private Long age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getAge() {
return age;
}
public void setAge(Long age) {
this.age = age;
}
}複製代碼
對應的配置文件和JavaBean創建完畢後,能夠直接經過註解注入,直接獲取常量的值。
@Resource
private UserProperty userProperty;
public static void main(String[] args) {
System.out.print("name: " + userProperty.getName() + " age: " + userProperty.getAge();")
}複製代碼
能夠使用AOP或者@ControllerAdvice註解來作全局控制。這裏使用註解的形式作全局的異常處理。發生異常時,跳轉到error.html頁面。
/java/包名/global/advice
@org.springframework.web.bind.annotation.ControllerAdvice
public class ControllerAdvice {
/** * 統一處理異常 * @param exception * @param webRequest * @return */
@ExceptionHandler(Exception.class)
public ModelAndView exception(Exception exception, WebRequest webRequest) {
return new ModelAndView("error");
}
}複製代碼
有些簡單的請求,直接返回視圖的,不用直接新建一個完整的controller,能夠經過配置直接路由。
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter{
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// 路由和視圖映射
registry.addViewController("/user").setViewName("/user");
}
}複製代碼
當訪問/user路由時,直接返回user.html頁面。
在請求的先後,對全局的請求作攔截。
/** * Created by wulei on 2017/6/8. * * 全局的時間攔截器 */
public class TimeInterceptor extends HandlerInterceptorAdapter{
private static Logger logger = Logger.getLogger(TimeInterceptor.class);
/** * 請求執行前 */
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
logger.debug(request.getServletPath() + " StartTime:" + System.currentTimeMillis());
return super.preHandle(request, response, handler);
}
/** * 請求執行後 */
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
logger.debug(request.getServletPath() + " EndTime:" + System.currentTimeMillis());
super.postHandle(request, response, handler, modelAndView);
}
}複製代碼
攔截器定義完成後,要在配置類中實例化。
/** * Created by wulei on 2017/6/8. * * 從新配置MVC */
@Configuration
public class WebMvcConfig extends WebMvcConfigurerAdapter{
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(timeInterceptor());
}
@Bean
public TimeInterceptor timeInterceptor(){
return new TimeInterceptor();
}
}複製代碼
在application.properties配置數據庫鏈接信息
# ----------- DB --------------------
spring.jpa.database=MYSQL
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test_spring_boot?serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root複製代碼
Maven中配置JDBC依賴和Spring Data JPA的依賴。JPA是Spring Data的子項目,能夠有效減小數據訪問層的代碼。
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>複製代碼
咱們能夠經過定義Bean來定義表結構,並經過正向工程直接在數據庫中生成相應的表。舉個User的例子。
@Entity
public class User {
@Id
@GeneratedValue
private Long id;
private Integer age;
private String name;
private String address;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}複製代碼
當工程啓動的時候,自動生成數據庫表。
經過繼承JpaRepository接口,實現數據庫操做。JpaRepository已經實現了一些基本的數據庫操做
public interface UserRepository extends JpaRepository<User, Long> {
// 按照地址查詢地址
List<User> findByAddress(String name);
}複製代碼
簡單數據庫操做能夠直接調用JpaRepository接口中定好的方法。如保存一個User對象。
@Autowired
public UserRepository userRepository;
public static void main(String[] args) {
User user = new User();
user.setName(name);
user.setAddress(address);
user.setAge(age);
userRepository.save(user);
}複製代碼
直接注入一個Repository。若是要自定義一個查詢地址的方法如上findByAddress便可。更多操做能夠參考官方文檔。
仍是不少東西能夠聊,如構建權限控制,緩存的使用,事務的使用,後面慢慢聊。喜歡歡迎點贊,打賞。