微服務就是將一個大的系統拆分紅多個子系統,而後經過REST風格的請求將他們集成起來,進一步簡化了分佈式系統的開發css
天天都在用SpringBoot缺不知道其中的原理,典型的日用而不知。一旦出現開發的問題,就是一頓博客亂找,好久也解決不了問題 因此,理解原理很重要java
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
@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
@Component("user")
public class User {
private id;
private String userName;
private String note;
}
@Service
public class System{
@Autowired
private User user;
}
複製代碼
@Service註解做用在類上
@Service註解做用域默認爲singleton
使用註解配置和類路徑掃描時,被@Service註解標註的類會被Spring掃描並註冊爲Bean
@Service註解用於標註業務的邏輯組件,即服務組件組件
複製代碼
@Repository註解做用在類上
@Repository註解做用域默認爲singleton
使用註解配置和類路徑掃描時,被@Repository註解標註的類會被Spring掃描並註冊爲Bean
@Repository註解用於標註數據訪問組件,即DAO組件
@Repository註解的做用不僅是將類識別爲Bean,同時它還能將所標註的類中拋出的數據訪問異常封裝爲 Spring 的數據訪問異常類型
複製代碼
@Controller註解做用在類上
使用註解配置和類路徑掃描時,被@Controller註解標註的類會被Spring掃描並註冊爲Bean
@Controller用於標註Web中控制層組件
被@Controller標註的類負責處理由DispatcherServlet分發的請求,
它把用戶請求的數據通過業務處理層處理以後封裝成一個Model ,而後再把該Model返回給對應的View進行展現
@Controller和@RequestMapping、@RequestParam等一些註解共同處理URL的映射
複製代碼
@ComponentScan意味着掃描當前註釋類所在的包和子包app
@SpringBootApplication默認包含了@ComponentScan
Spring最經常使用的註解,根據類型找到對應的Bean進行注入,也就是getBeanByType()
public interface User {
}
@Component
@Primary
public class Man implements {
}
@Component
public class Woman implements {
}
public class System{
@Autowired
private User user;
這裏裝配的是Woman
}
複製代碼
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){};
}
複製代碼
從配置文件中獲取屬性
@Component
@ConfigurationProperties(prefix = "microservice.quickstart")
public class User{
@Value('${user.name}')
private String userName;
//讀取配置文件中的microservice.quickstart.user.name配置
}
複製代碼
按照工程創建
@Scope用來配置Bean的做用域,有如下幾種
Spring 容器中有且只有一個Bean實例,只要Spring容器不銷燬或退出,該Bean實例就會一直存活
每次獲取Bean的時候會有一個新的實例,Spring容器不能對返回Bean實例的整個生命週期負責
request只適用於Web程序,每一次HTTP請求都會產生一個新的bean, 同時該bean僅在當前HTTP request內有效,當請求結束後,該對象的生命週期即告結束
session只適用於Web程序,session做用域表示該針對每一次HTTP請求都會產生一個新的bean, 同時該bean僅在當前HTTP session內有效
application只適用於Web程序,全局做用域
這句代碼能夠標註在類上面,表示該類下面的全部@Bean都會啓用配置,也能夠標註在方法上面,只是對該方法啓用配置。
@ConditionalOnBean(僅僅在當前上下文中存在某個對象時,纔會實例化一個Bean) @ConditionalOnClass(某個class位於類路徑上,纔會實例化一個Bean) @ConditionalOnExpression(當表達式爲true的時候,纔會實例化一個Bean) @ConditionalOnMissingBean(僅僅在當前上下文中不存在某個對象時,纔會實例化一個Bean) @ConditionalOnMissingClass(某個class類路徑上不存在的時候,纔會實例化一個Bean) @ConditionalOnNotWebApplication(不是web應用)
@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提供了類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-principle.png
spring-intercetor.png
Spring AOP使用@AspectJ對方法進行攔截,因此,咱們要先肯定什麼地方須要AOP,也就是鏈接點 有了鏈接點後,咱們須要一個切面,用來描述流程的織入 請看案例:
MyAspect.java
@Transactional能夠放在方法上,也能夠放在類上 若是放在類上,則該類的全部方法都默認帶了@Transactional 案例請查看
com.liuyiling.microservice.api.controller.DataBaseController.transactional
事務的隔離度,默認值採用 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)