1.過濾器
??1.為什么要使用過濾器
??在Web開發中,常常會有這樣的需求:在所有介面中去除用戶輸入的非法字符,以防止引起業務例外,要實作這個功能,可以有很多方法,如:
- 在前端引數傳入時進行校驗,先過濾掉非法字符,然后,回傳用戶界面提示用戶重新輸入,
- 后端接收前端沒有過濾的資料,然后過濾非法字符,
- 利用Filter處理頊目中所有非法字符,
??很明顯,前兩種實作方法會存在重復代碼,因為每個前端頁面或后端都需要處理,這樣會導致 代碼極難維護,如果用過濾器來實作,則只需要用過濾器利所有介面進行過濾處理,這樣非常方便, 同時不會岀現冗余代碼,
??2.使用Filter的步驟
(1)新建類,實作Filter抽象類,
(2)重寫 init、doFilter、destroy 方法,
(3)在 Spring Boot 入口中添加注解@ServletComponentScan,以注冊 Filter
???詳細步驟如下:
????(1)撰寫過濾器類,
package com.itheima.filter;
import org.springframework.core.annotation.Order;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;
@Order(1)
//定義此過濾器在過濾器鏈中的位置,序號越小越先被執行
@WebFilter(filterName = "filterdemo",urlPatterns = "/*")
//URL過濾配置
public class FilterDemo implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
//init方法,將在服務器啟動時被呼叫
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
//request 請求處理邏輯
//response 請求封裝邏輯
//chain重新寫回request和response
}
@Override
public void destroy() {
//重寫detory邏輯,該邏輯將在服務器關閉時被呼叫
}
}
????(2)在Spring Boot入口類中注冊Filter.
????要在 Spring Boot 入口類中注冊 Filter,只需要添加注解@ServletComponentScan
2.監聽器
??監聽器(Listener)用于監聽Web應用程式中某些対象或資訊的創建、銷毀、增加、修改、洗掉等動作,然后做出相應的回應處理,當対象的狀態發生變化時,服務器自動呼叫監聽器的方法,監聽器常用于統計在線人數、在線用戶、系統加載時的資訊初始化等,
Servlet中的監聽器分為以下3種型別,
- 監聽ServletContext、Requests、Session作用域的創建和銷毀
- ServletContextListener:監聽 ServeltContext,
- HttpSessionListener:監聽新的 Session 創建事件,
- ServletRequestListener:監聽 ServletRequest 的初始化和銷毀,
- 監聽ServletContext、Request、Session作用域中屬性的變化(增加、修改、洗掉)
- ServletContextAttributeListener:監聽 Servlet 背景關系引數的變化,
- HttpSessionAttributeListener:監聽 HttpSession 引數的變化,
- ServletRequestAttnbuteListener:監聽 Se「vletRequest 引數的變化,
- 監聽HttpSession中物件狀態的改變(被系結、解除系結、鈍化、活化)
- HltpSessionBindingListener:監聽 HttpSession,并系結及解除系結,
- HttpSessionActivationListener:監聽鈍化和活動的 HttpSession 狀態改變,
??實體:實作監聽器
??1.實作監聽器
??通過注解@WebListener標注此類是監聽器
package com.itheima.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
@WebListener
public class ListenerDemo implements ServletContextListener{
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("ServletContextInitialized");
System.out.println(sce.getServletContext().getServerInfo());
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("ServletContextDestroyed");
}
}
??2.開啟監聽器Bean掃描
??在入口類上,添加注解@ServletComponentScan 啟動專案后,在控制臺中會輸岀以下資訊:
????ServletContextInitialized????Apache Tomcat/9.0.41
??如果不停止,在埠被占用的情況下重新啟動,則顯示以下資訊:
???Stopping service [Tomcat]
???ServletContextDestroyed
3.自動配置
??1.自定義入口類
??入口類默認提供了注解@SpringBootApplication,它用于標注Spring Boot專案的入口,這 個注解被@Configuration、 @EnableAutoConfiguration、@ComponentScan 三個注解所修飾, 即Spring Boot提供了統一的注解來替代這三個注解,
用這三個注解替代注解?SpringBootApplication也是合法的,見以下代碼:
package com.itheima;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Springboot05MybatisApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot05MybatisApplication.class, args);
}
}
??上面的“run”方法實體化了一個“SpringApplication”物件,執行run方法,見以下代碼:
/**
* Static helper that can be used to run a {@link SpringApplication} from the
* specified source using default settings.
* @param primarySource the primary source to load
* @param args the application arguments (usually passed from a Java main method)
* @return the running {@link ApplicationContext}
*/
public static ConfigurableApplicationContext run(Class<?> primarySource, String... args) {
return run(new Class<?>[] { primarySource }, args);
}
??如果把入口類的“run”方法改成下方的代碼,則效果也是一樣的:
package com.itheima;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan
@SpringBootApplication
public class Springboot05MybatisApplication {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(SpringBootApplication.class);
application.run(args);
}
}
??解釋:
public SpringApplication(Class<?>... primarySources) { this(null, primarySources);}
???創建一個新的SpringApplication實體,應用程式背景關系將從指定的主要來源加載 bean(有關詳細資訊,請參閱class-level檔案,可以在呼叫run(String...)之前自定義實體,
???如果需要創建多層次的"Applicationcontext”,則可以使用SpringApplicationBuilder將 多個方法呼叫串聯起來,然后通過“parent()和child()”來創建,見以下代碼:
package com.itheima;
import javafx.scene.Parent;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.ServletComponentScan;
@ServletComponentScan
@SpringBootApplication
public class Springboot05MybatisApplication {
public static void main(String[] args) {
new SpringApplicationBuilder()
.sources(Parent.class)
.child(Springboot05MybatisApplication.class)
.run(args);
}
}
public SpringApplicationBuilder(Class<?>... sources) { this.application = createSpringApplication(sources);}
SpringApplicationBuilder:
SpringApplication和ApplicationContext實體的構建器,具有方便的流暢 API 和背景關系層次結構支持,背景關系層次結構的簡單示例:
new SpringApplicationBuilder(ParentConfig.class).child(ChildConfig.class).run(args);
另一個常見用例是設定活動組態檔和默認屬性以設定應用程式的環境:
new SpringApplicationBuilder(Application.class).profiles("server")
.properties("transport=local").run(args);
如果您的需求更簡單,請考慮使用 SpringApplication 中的靜態便捷方法,
??2.自動配置的原理
在入口類中,默認使用了注解@EnableAutoConfiguration,Spring Boot也正是通過它來完成自動配置的,
注解@EnableAutoConfiguration借助注解@Import,將所有符合自動配置條件的Bean都加載到loC容器中,其關鍵代碼如下:
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
/**
* Environment property that can be used to override when auto-configuration is
* enabled.
*/
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
/**
* Exclude specific auto-configuration classes such that they will never be applied.
* @return the classes to exclude
*/
Class<?>[] exclude() default {};
/**
* Exclude specific auto-configuration class names such that they will never be
* applied.
* @return the class names to exclude
* @since 1.3.0
*/
String[] excludeName() default {};
}
從上述代碼可以看到,在 EnableAutoConfiguration 類中匯入了 "AutoConfigurationlmport- Selector.class\ Spring Boot借助它將所有符合條件的?Configuration配置都加載到loC容 器中,EnableAutoConfiguration 類還會匯入 Sp「ingFacto「iesLoader 類,進入 SpringFactories- Loader類中可以看到,其關鍵代碼如下:
public final class SpringFactoriesLoader {
??public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";
??private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class);
}//省略
從上述代碼可以看到,SpringFactoriesLoader從classpath中尋找所有的META-INF/spring.factories 組態檔,

??通過上面的SpringFactoriesLoader代碼和原理圖可以看出Spring Boot自動配置原理 (EnableAutoConfiguration 類)的作業原理:它借助 AutoConfiguralionlmportSelector,呼叫 SpringFactoriesLoader 的 loadFactoryNames 方法,從 classpath 中尋找所有的 META-INF/spring.factories組態檔(spring.factories配置了自動裝配的類);然后,再借助 AutoConfigurationlmportSelector,將所有符合條件的@Configuration 配置都加載到loC容器中,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/499509.html
標籤:Java
上一篇:String型別函式傳遞問題
