Spring底層機制環(huán)境搭建全過程
更新時間:2024年12月09日 10:50:31 作者:S-X-S
本文介紹了如何創(chuàng)建和使用Spring框架,包括模塊創(chuàng)建、依賴引入、環(huán)境搭建、Bean的生命周期管理、AOP編程以及代碼托管,通過實際操作和代碼示例,詳細講解了Spring的核心概念和功能
Spring底層機制環(huán)境搭建
1.模塊創(chuàng)建和依賴引入
聚合模塊,下面有一個myspring
查看父模塊是否管理了子模塊
myspring模塊引入基本包
<dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.3.8</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.3.8</version> </dependency> </dependencies>
2.進行環(huán)境搭建
目錄概覽
UserController.java
package com.sunxiansheng.myspring.component; import org.springframework.stereotype.Component; /** * Description: 就是一個Controller組件 * @Author sun * @Create 2024/8/4 13:53 * @Version 1.0 */ @Component public class UserController { }
UserService.java
package com.sunxiansheng.myspring.component; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; /** * Description: 一個Service組件 * @Author sun * @Create 2024/8/4 13:54 * @Version 1.0 */ @Component public class UserService { /** * 依賴注入UserDao */ @Autowired private UserDao userDao; public void add() { System.out.println("UserService 調(diào)用了UserDao的add方法"); userDao.add(); } }
UserDao.java
package com.sunxiansheng.myspring.component; import org.springframework.stereotype.Component; /** * Description: 一個Dao組件 * @Author sun * @Create 2024/8/4 13:53 * @Version 1.0 */ @Component public class UserDao { public void add() { System.out.println("UserDao add..."); } }
AppMain.java
package com.sunxiansheng.myspring; import com.sunxiansheng.myspring.component.UserController; import com.sunxiansheng.myspring.component.UserDao; import com.sunxiansheng.myspring.component.UserService; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Description: 啟動類 * @Author sun * @Create 2024/8/4 13:59 * @Version 1.0 */ public class AppMain { public static void main(String[] args) { // 從類路徑下加載beans.xml配置文件 ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml"); // 從容器中獲取UserController對象,這里獲取兩次,看是否是同一個對象 UserController userController1 = (UserController) ioc.getBean("userController"); UserController userController2 = (UserController) ioc.getBean("userController"); System.out.println("userController1 == userController2 ? " + (userController1 == userController2)); // 從容器中獲取UserService對象 UserService userService = (UserService) ioc.getBean("userService"); System.out.println("userService = " + userService); // 從容器中獲取UserDao對象 UserDao userDao = (UserDao) ioc.getBean("userDao"); System.out.println("userDao = " + userDao); } }
beans.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!-- 配置自動掃描的包 --> <context:component-scan base-package="com.sunxiansheng.myspring.component"/> </beans>
測試
配置UserController.java為多例的,然后測試
UserService調(diào)用add方法,然后測試
引入Bean后置處理器
1.位置
2.MyBeanPostProcessor.java
package com.sunxiansheng.myspring.process; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.stereotype.Component; /** * Description: Bean的后置處理器 * @Author sun * @Create 2024/8/4 14:19 * @Version 1.0 */ @Component // 將這個類加入到容器中 public class MyBeanPostProcessor implements BeanPostProcessor { /** * 在每個Bean的初始化方法之前執(zhí)行 * @param bean * @param beanName * @return */ @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { // 這里可以提前對bean進行一些處理 System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean.getClass()); return bean; } /** * 在每個Bean的初始化方法之后執(zhí)行 * @param bean * @param beanName * @return */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) { System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean.getClass()); return bean; } }
3.UserService.java 設(shè)置初始化方法
4.beans.xml配置掃描
5.測試
6.注意事項
- bean的后置處理器在初始化方法調(diào)用前后執(zhí)行
- 觸發(fā)時機為單例的第一次getBean和多例的每次getBean,也就是,每個Bean都會經(jīng)過Bean的后置處理器處理
引入AOP
1.目錄
2.SmartAnimal.java
package com.sunxiansheng.myspring.aop; /** * Description: SmartAnimal * @Author sun * @Create 2024/8/4 14:51 * @Version 1.0 */ public interface SmartAnimal { public float getSum(float a, float b); public float getSub(float a, float b); }
3.SmartDog.java
package com.sunxiansheng.myspring.aop; import org.springframework.stereotype.Component; /** * Description: SmartDog * @Author sun * @Create 2024/8/4 14:51 * @Version 1.0 */ @Component // 交給Spring容器管理 public class SmartDog implements SmartAnimal { @Override public float getSum(float a, float b) { System.out.println("SmartDog...getSum...res=" + (a + b)); return a + b; } @Override public float getSub(float a, float b) { System.out.println("SmartDog...getSub...res=" + (a - b)); return a - b; } }
4.SmartAnimalAspect.java
package com.sunxiansheng.myspring.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.Signature; import org.aspectj.lang.annotation.*; import org.aspectj.lang.reflect.MethodSignature; import org.springframework.stereotype.Component; import java.util.Arrays; /** * Description: 切面類 * @Author sun * @Create 2024/8/4 14:53 * @Version 1.0 */ @Component // 交給Spring容器管理 @Aspect // 標(biāo)注這是一個切面類 public class SmartAnimalAspect { /** * @param joinPoint 保存了要切入的方法的信息 * @Before 前置通知 * execution(。。。) 切入表達式,表明要切入的方法,格式:格式:訪問修飾符+返回類型 全類名 方法名(參數(shù)類型) */ @Before(value = "execution(public float com.sunxiansheng.myspring.aop.SmartDog.getSub(float, float))") public void before(JoinPoint joinPoint) { // 獲取方法簽名 Signature signature = joinPoint.getSignature(); System.out.println("方法執(zhí)行開始-日志-方法名-" + signature.getName() + "-參數(shù)" + Arrays.asList(joinPoint.getArgs())); // 還可以獲取目標(biāo)對象,這樣就可以反射進行任何操作了 SmartDog target = (SmartDog) joinPoint.getTarget(); System.out.println("目標(biāo)對象-" + target.getClass()); } /** * @param joinPoint 保存了要切入的方法的信息 * @AfterReturning 返回通知 */ @AfterReturning(value = "execution(public float com.sunxiansheng.myspring.aop.SmartDog.getSub(float, float))") public void afterReturning(JoinPoint joinPoint) { Signature signature = joinPoint.getSignature(); System.out.println("方法執(zhí)行正常結(jié)束-日志-方法名-" + signature.getName()); } /** * @param joinPoint * @AfterThrowing 異常通知 */ @AfterThrowing(value = "execution(public float com.sunxiansheng.myspring.aop.SmartDog.getSub(float, float))") public void throwing(JoinPoint joinPoint) { Signature signature = joinPoint.getSignature(); System.out.println("方法出現(xiàn)異常-日志-方法名-" + signature.getName()); } /** * @param joinPoint * @After 后置通知 */ @After(value = "execution(public float com.sunxiansheng.myspring.aop.SmartDog.getSub(float, float))") public void after(JoinPoint joinPoint) { Signature signature = joinPoint.getSignature(); System.out.println("方法最終執(zhí)行完畢-日志-方法名-" + signature.getName()); } /** * 環(huán)繞通知 * @param joinPoint * @return * @throws Throwable */ @Around("execution(public float com.sunxiansheng.myspring.aop.SmartDog.getSub(float, float))") public Object logMethodExecution(ProceedingJoinPoint joinPoint) throws Throwable { MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 獲取方法信息 String methodName = signature.getMethod().getName(); String className = signature.getDeclaringType().getSimpleName(); System.out.println("環(huán)繞通知 method " + className + "." + methodName); // 獲取目標(biāo)對象 Object targetObject = joinPoint.getTarget(); // 環(huán)繞通知獲取目標(biāo)對象 System.out.println("環(huán)繞通知獲取目標(biāo)對象:" + targetObject); try { // 前置通知:環(huán)繞通知獲取參數(shù) System.out.println("環(huán)繞通知獲取參數(shù):" + Arrays.asList(joinPoint.getArgs())); Object result = joinPoint.proceed(); // 執(zhí)行目標(biāo)方法 // 返回通知:環(huán)繞通知獲取結(jié)果 System.out.println("環(huán)繞通知獲取結(jié)果:" + result); return result; } catch (Exception e) { // 異常通知 throw e; } finally { // 最終通知 System.out.println("環(huán)繞通知 method " + className + "." + methodName); } } }
5.beans.xml開啟aop注解并掃描aop包
6.AppMain.java 測試AOP
6.簡單分析AOP和后置處理器的關(guān)系
3.拋出問題
- 1.bean是怎么注入容器的?
- 2.為什么加了@Autowired就能被依賴注入?
- 3.單例多例是怎么實現(xiàn)的?
- 4.Bean的后置處理器是怎么實現(xiàn)的?
- 5.原生Spring的AOP是如何實現(xiàn)的?
4.將代碼放到遠程倉庫
- VCS -》 share
- 查看倉庫
總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
java實現(xiàn)excel導(dǎo)入數(shù)據(jù)的工具類
這篇文章主要介紹了java實現(xiàn)的excel導(dǎo)入數(shù)據(jù)的工具類,需要的朋友可以參考下2014-03-03詳解IDEA 啟動tomcat 端口占用原因以及解決方法( 使用debug模式)
這篇文章主要介紹了詳解IDEA 啟動tomcat 端口占用原因以及解決方法( 使用debug模式) ,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-08-08