SpringBoot2

SpringBoot2

微服務的概念

微服務就是將一個大的系統拆分紅多個子系統,而後經過REST風格的請求將他們集成起來,進一步簡化了分佈式系統的開發css

SpringBoot2的特色

  • 約定大於配置,經過引入xx-starter加上自定義的配置文件就能夠集成某個組件的java客戶端
  • 內置tomcat/undertow
  • 提供快速的測試環境

爲何要學這個

天天都在用SpringBoot缺不知道其中的原理,典型的日用而不知。一旦出現開發的問題,就是一頓博客亂找,好久也解決不了問題 因此,理解原理很重要java

Bean的聲明週期

1.Spring經過配置,如@SpringBootApplication或@ComponentScan定義的路徑(默認爲當前包和子包)找到帶有@Component的類web

2.解析類定義,把Bean定義發佈到Ioc容器中,注意:是定義,不是實例spring

3.Ioc容器裝載Bean的定義數據庫

4.建立Bean的實例對象api

5.開始掃描@Autowired注入各種資源tomcat

踩坑

@Service
public class Service{
    @Autowired
    public String kafkaHost;
    
    public KafkaAppender;
    public Service(){
        KafkaAppender = new KafkaAppender(kafkaHost);
    }
}
複製代碼

注意,當Service被初始化時,會調用構造器,此時kafkaHost還沒被Autowired注入,因此這個時候kafkaHost爲nullbash

Spring註解說明

Spring註解之Bean註解:

@Configuration
public class AppConfig {
    @Bean(name="user"} 
    public User initUser () {
        User user= new User (); 
        user.setId(100) ;
        user.setUserName();
        return user;
    }
}

@Service    
public class System{
    @Autowired
    private User user;
}   
複製代碼

@Bean表示將initUser返回的user裝配到Ioc中,並且該bean的name爲user。若是沒有定義name,則bean的name爲方法名(initUser)session

@ComponentScan與@Component

@Component("user")
public class User {
    private id; 
    private String userName; 
    private String note;
}

@Service    
public class System{
    @Autowired
    private User user;
}    
複製代碼

注意事項

  • @Component註解做用域默認爲singleton
  • @Component表名這個類將被Ioc裝配,並且該bean的name爲user,若是沒有顯示定義name,則以類名第一個字母小寫做爲bean的name
  • @Component使用在不肯定哪個層的時候使用,能夠做用在任何層次,把普通pojo實例化到spring容器
  • 不推薦使用@Component註解,而應該使用它的擴展,如@Service、@Repository

業務組件的註釋

  • @Component 沒有明確角色的組件
  • @Service 在業務邏輯層(Service層)使用
  • @Repository 在數據訪問層(dao層)使用
  • @Controller 用於標註控制層組件
  • @RestController 純REST風格的控制器
@Service
@Service註解做用在類上
@Service註解做用域默認爲singleton
使用註解配置和類路徑掃描時,被@Service註解標註的類會被Spring掃描並註冊爲Bean
@Service註解用於標註業務的邏輯組件,即服務組件組件
複製代碼
@Repository
@Repository註解做用在類上
@Repository註解做用域默認爲singleton
使用註解配置和類路徑掃描時,被@Repository註解標註的類會被Spring掃描並註冊爲Bean
@Repository註解用於標註數據訪問組件,即DAO組件
@Repository註解的做用不僅是將類識別爲Bean,同時它還能將所標註的類中拋出的數據訪問異常封裝爲 Spring 的數據訪問異常類型
複製代碼

@Controller

@Controller註解做用在類上
使用註解配置和類路徑掃描時,被@Controller註解標註的類會被Spring掃描並註冊爲Bean
@Controller用於標註Web中控制層組件
被@Controller標註的類負責處理由DispatcherServlet分發的請求,
它把用戶請求的數據通過業務處理層處理以後封裝成一個Model ,而後再把該Model返回給對應的View進行展現
@Controller和@RequestMapping、@RequestParam等一些註解共同處理URL的映射
複製代碼

@ComponentScan意味着掃描當前註釋類所在的包和子包app

@SpringBootApplication

@SpringBootApplication默認包含了@ComponentScan

@Autowired、@Primary、@Qualifier

Spring最經常使用的註解,根據類型找到對應的Bean進行注入,也就是getBeanByType()

  • 首先根據類型找到對應類型的Bean,若是不惟一,則按照Bean名稱進行匹配,若是還找不到,就拋異常
  • 當對應類型的Bean有多個時,@Primary告訴Ioc容器,優先使用帶有@Primary標識的Bean
public interface User {
}
@Component
@Primary
public class Man implements {
}
@Component
public class Woman implements {
}

public class System{
    @Autowired
    private User user;
    這裏裝配的是Woman
}
複製代碼
  • @Qualifier告訴Ioc容器按照類型和名稱去找到對應的Bean
public interface User {
}
@Component
@Primary
public class Man implements {
}
@Component
@Primary
public class Woman implements {
}

public class System{
    @Autowired
    @Qualiefier("man")
    private User user;
    這裏裝配的是Man
    
    public void heiheihei(@Autowired @Qualiefier("man") User user){};
}
複製代碼

@Value與@ConfigurationProperties

從配置文件中獲取屬性

@Component
@ConfigurationProperties(prefix = "microservice.quickstart")
public class User{
    @Value('${user.name}')
    private String userName;
    //讀取配置文件中的microservice.quickstart.user.name配置
}

複製代碼

多環境配置下的啓動

按照工程創建

  • application.properties
  • application-dev.properties
  • application-test.properties
  • application-prd.properties 啓動時添加命令做爲參數 java -jar xx.jar -Dpsirng.profiles.active=dev java -jar xx.jar -Dpsirng.profiles.active=test java -jar xx.jar -Dpsirng.profiles.active=prd

@Scope做用在類上和方法上

@Scope用來配置Bean的做用域,有如下幾種

singleton單例模式

Spring 容器中有且只有一個Bean實例,只要Spring容器不銷燬或退出,該Bean實例就會一直存活

prototype原型模式

每次獲取Bean的時候會有一個新的實例,Spring容器不能對返回Bean實例的整個生命週期負責

request模式

request只適用於Web程序,每一次HTTP請求都會產生一個新的bean, 同時該bean僅在當前HTTP request內有效,當請求結束後,該對象的生命週期即告結束

session模式

session只適用於Web程序,session做用域表示該針對每一次HTTP請求都會產生一個新的bean, 同時該bean僅在當前HTTP session內有效

application模式

application只適用於Web程序,全局做用域

@Conditional(TestCondition.class)

這句代碼能夠標註在類上面,表示該類下面的全部@Bean都會啓用配置,也能夠標註在方法上面,只是對該方法啓用配置。

@ConditionalOnBean(僅僅在當前上下文中存在某個對象時,纔會實例化一個Bean) @ConditionalOnClass(某個class位於類路徑上,纔會實例化一個Bean) @ConditionalOnExpression(當表達式爲true的時候,纔會實例化一個Bean) @ConditionalOnMissingBean(僅僅在當前上下文中不存在某個對象時,纔會實例化一個Bean) @ConditionalOnMissingClass(某個class類路徑上不存在的時候,纔會實例化一個Bean) @ConditionalOnNotWebApplication(不是web應用)

spring源碼閱讀

@EnableWebMvc、WebMvcConfigurationSupport和WebMvcConfigurationAdapter三者之間的區別是什麼 @EnableWebMvc註解的類等於extends WebMvcConfigurationSupport 可是沒有重寫任何方法 SpringBoot WebMVC的自動配置信息都在WebMvcAutoConfiguration這個類中,咱們看他的源碼

@Configuration
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638) //Bean的初始化順序
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration {
複製代碼

其中@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})的意思是,當工程中沒有WebMvcConfigurationSupport 時,纔會使用WebMvc的自動配置;咱們通常會繼承WebMvcConfigurationSupport來自定義配置類, 可是一旦繼承WebMvcConfigurationSupport後就會出現新的問題: 會發現Spring Boot的WebMvc自動配置失效,具體表現好比訪問不到靜態資源(js,css等)了。

攔截器原理

動態代理

上海體育公園有不少大爺大媽相親,你要去尋找女友。這時,你就問大媽:女兒喜歡什麼呀,大媽可能會替她回答。 固然,大媽以爲你髮際線過高,他也能夠直接拒絕。這時,這個大媽就是她女兒的代理

JDK中的使用方式

JDK提供了類Proxy的靜態方法:newProxyInstance.

public static Object newProxyInstance(ClassLoader var0, Class<?>[] var1, InvocationHandler var2) throws IllegalArgumentException

這裏的invocationHandler是一個接口InvocationHandler對象,定義了invoke方法,這個方法就是實現代理對象邏輯的 經過target\method\args就可以用反射方法運行了

具體見:ProxyBean.java[請學會用IDEA找到對應名字的類]

AOP約定流程

按照咱們上面實現的代碼,能夠看到,AOP是一種規範化的約定,咱們按照這種約定來使用,就能夠實現動態代理 aop-principle.png

攔截器使用AOP的約定

spring-intercetor.png

Spring中使用@AspectJ

Spring AOP使用@AspectJ對方法進行攔截,因此,咱們要先肯定什麼地方須要AOP,也就是鏈接點 有了鏈接點後,咱們須要一個切面,用來描述流程的織入 請看案例:

MyAspect.java

Myabits中的數據庫事務

@Transactional能夠放在方法上,也能夠放在類上 若是放在類上,則該類的全部方法都默認帶了@Transactional 案例請查看

com.liuyiling.microservice.api.controller.DataBaseController.transactional

注意事項

  • @Transactional必須加在public方法上,不然CGlib代理會找不到
  • 正確的設置@Transactional 的 isolation 屬性

事務的隔離度,默認值採用 DEFAULT

  • 事務必須註解在非自調用方法上,下面面這個例子事務將不會被調用
@Service
public class OrderService {
    private void insert() {
        insertOrder();
    }
    
    @Transactional
    public void insertOrder() {
    }
}
複製代碼
  • 能夠指定事務的回滾條件

默認狀況下,若是在事務中拋出了未檢查異常(繼承自 RuntimeException 的異常)或者 Error,則 Spring 將回滾事務;除此以外,Spring 不會回滾事務。 若是在事務中拋出其餘類型的異常,並指望 Spring 可以回滾事務,能夠指定 rollbackFor。例: @Transactional(propagation= Propagation.REQUIRED,rollbackFor= MyException.class)

相關文章
相關標籤/搜索