spring與web的整合
1. 整合的原理:
Spring容器隨着tomcat容器ServletContext的啓動而啓動,並且在初始化完成後放到整個應用都可以訪問的範圍。
ApplicationContext隨着服務器的啓動而啓動,可以藉助與Servlet/Filter/Listener任何一個;
把創建好的ApplicationContext放到ServletContext中,整個應用範圍,想怎訪問就怎麼訪問;
spring-web-4.2.4.RELEASE.jar包中提供了Listener的支持(spring建議的方式)
WebApplicationContextUtils是Spring官方提供的一個web環境下便捷從ServletContext中獲取ApplicationContext的工具類。
2. 整合的步驟
● 添加依賴
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.2.4.RELEASE</version> </dependency> <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency>
● 配置監聽器,監聽web項目的啓動
<!-- needed for ContextLoaderListener --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> <!-- Bootstraps the root web application context before servlet initialization --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
● 創建servlet,在servlet中獲取spring容器
1 public class ContextServlet extends HttpServlet { 2 private static final long serialVersionUID = 1L; 3 4 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 5 // 1. 獲取spring容器 6 // 獲取servletContext域對象 7 ServletContext servletContext = getServletContext(); 8 // web環境的spring容器 9 WebApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(servletContext); 10 // 2. 從容器中獲取javabean對象 11 Person person = (Person) applicationContext.getBean("person4"); 12 System.out.println(person.getUsername()); 13 response.getWriter().append("Served at: ").append(request.getContextPath()); 14 } 15 16 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 17 doGet(request, response); 18 } 19 }
● 訪問servlet進行測試
瀏覽器訪問:http://localhost:8080/ContextServlet
spring容器基於註解方式的開發
● 優缺點:
缺點:
1、如果所有的內容都配置在.xml文件中,那麼.xml文件將會十分龐大;如果按需求分開.xml文件,那麼.xml文件又會非常多。總之這將導致配置文件的可讀性與可維護性變得很低。
2、在開發中在.java文件和.xml文件之間不斷切換,是一件麻煩的事,同時這種思維上的不連貫也會降低開發的效率。
優點:
Spring基於註解方式的開發,通過"@XXX"的方式,讓註解與Java Bean緊密結合,既大大減少了配置文件的體積,又增加了Java Bean的可讀性與內聚性。
● 開發步驟:
導入依賴
<!-- https://mvnrepository.com/artifact/org.springframework/spring-aop --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.2.4.RELEASE</version> </dependency>
添加context命名空間的schema
開啓註解掃描context:component-scan
<!-- 開啓spring的註解掃描 --> <!-- 掃描包下帶註釋的類及類中帶註釋的屬性 --> <context:component-scan base-package="spring.annotation.demo"></context:component-scan>
添加註解
Spring中和注入相關的常見註解有Autowired、Resource、Qualifier、Service、Controller、Repository、Component。
- Autowired是自動按照類型注入,自動從spring的上下文找到合適的bean來注入
- Resource用來指定名稱注入
- Qualifier和Autowired配合使用,指定bean的名稱
- Service,Controller,Repository分別標記類是Service層類,Controller層類,數據存儲層的類,spring掃描註解配置時,會標記這些類要生成bean。
- Component是一種泛指,標記類是組件,spring掃描註解配置時,會標記這些類要生成bean。
上面的Autowired和Resource是用來修飾字段,並做屬性注入的。而Service,Controller,Repository,Component則是用來修飾類,標記這些類要生成bean。
1 @Repository 2 public class CarDao { 3 public void insertCar(){ 4 System.out.println("CarDao中的insertCar的方法被調用... ..."); 5 } 6 }
1 @Service 2 //@Component 3 @Scope(value="singleton") 4 public class CarService { 5 // 自動按照類型注入,自動從spring上下文中找到合適的bean來注入 6 @Autowired 7 private CarDao carDao; 8 9 public void insertCar(){ 10 carDao.insertCar(); 11 System.out.println("CarService中的insertCar方法"); 12 } 13 14 @PostConstruct 15 public void init(){ 16 System.out.println("init方法被調用... ..."); 17 } 18 19 @PreDestroy 20 public void destory(){ 21 System.out.println("destory方法被調用... ..."); 22 } 23 }
編寫測試代碼
1 public static void main(String[] args) { 2 ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext-annotation.xml"); 3 CarService bean = (CarService) applicationContext.getBean("carService"); 4 bean.insertCar(); 5 }
@Autowired + @Qualifier 結合使用:指定注入bean的名稱
@Resouce註解:@Resource註解實現的效果和@Autowired+@Qualifier的效果是一樣的
@Scope用於指定scope作用域的(用在類上)
@PostConstruct用於指定初始化方法(用在方法上)
@PreDestory用於指定銷燬方法(用在方法上)
@Value 可以爲我們的基本數據類型以及string進行屬性賦值
xml配置方式與註解方式的對比
spring與Junit整合測試
整合後測試的優點
整合後測試變得非常簡單
避免頻繁、重複的容器加載
整合Junit的步驟
導入spring-test的jar包
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.12</version> <scope>test</scope> </dependency>
編寫Junit整合測試類
1 @RunWith(SpringJUnit4ClassRunner.class)//使用Junit4進行測試 2 @ContextConfiguration("classpath:applicationContext-annotation.xml")//加載配置文件 3 public class JunitSpringTest { 4 @Autowired 5 private CarService carService; 6 7 @Autowired 8 private CarDao carDao; 9 10 @Test 11 public void test01(){ 12 carDao.insertCar(); 13 } 14 }