Spring底層機(jī)制環(huán)境搭建全過程
Spring底層機(jī)制環(huán)境搭建
1.模塊創(chuàng)建和依賴引入
聚合模塊,下面有一個(gè)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.進(jìn)行環(huán)境搭建
目錄概覽

UserController.java
package com.sunxiansheng.myspring.component;
import org.springframework.stereotype.Component;
/**
* Description: 就是一個(gè)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: 一個(gè)Service組件
* @Author sun
* @Create 2024/8/4 13:54
* @Version 1.0
*/
@Component
public class UserService {
/**
* 依賴注入U(xiǎn)serDao
*/
@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: 一個(gè)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: 啟動(dòng)類
* @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對(duì)象,這里獲取兩次,看是否是同一個(gè)對(duì)象
UserController userController1 = (UserController) ioc.getBean("userController");
UserController userController2 = (UserController) ioc.getBean("userController");
System.out.println("userController1 == userController2 ? " + (userController1 == userController2));
// 從容器中獲取UserService對(duì)象
UserService userService = (UserService) ioc.getBean("userService");
System.out.println("userService = " + userService);
// 從容器中獲取UserDao對(duì)象
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">
<!-- 配置自動(dòng)掃描的包 -->
<context:component-scan base-package="com.sunxiansheng.myspring.component"/>
</beans>測(cè)試

配置UserController.java為多例的,然后測(cè)試


UserService調(diào)用add方法,然后測(cè)試


引入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 // 將這個(gè)類加入到容器中
public class MyBeanPostProcessor implements BeanPostProcessor {
/**
* 在每個(gè)Bean的初始化方法之前執(zhí)行
* @param bean
* @param beanName
* @return
*/
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
// 這里可以提前對(duì)bean進(jìn)行一些處理
System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean.getClass());
return bean;
}
/**
* 在每個(gè)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.測(cè)試

6.注意事項(xiàng)
- bean的后置處理器在初始化方法調(diào)用前后執(zhí)行
- 觸發(fā)時(shí)機(jī)為單例的第一次getBean和多例的每次getBean,也就是,每個(gè)Bean都會(huì)經(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)注這是一個(gè)切面類
public class SmartAnimalAspect {
/**
* @param joinPoint 保存了要切入的方法的信息
* @Before 前置通知
* execution(。。。) 切入表達(dá)式,表明要切入的方法,格式:格式:訪問修飾符+返回類型 全類名 方法名(參數(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)對(duì)象,這樣就可以反射進(jìn)行任何操作了
SmartDog target = (SmartDog) joinPoint.getTarget();
System.out.println("目標(biāo)對(duì)象-" + 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)對(duì)象
Object targetObject = joinPoint.getTarget();
// 環(huán)繞通知獲取目標(biāo)對(duì)象
System.out.println("環(huán)繞通知獲取目標(biāo)對(duì)象:" + 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 測(cè)試AOP


6.簡(jiǎn)單分析AOP和后置處理器的關(guān)系

3.拋出問題
- 1.bean是怎么注入容器的?
- 2.為什么加了@Autowired就能被依賴注入?
- 3.單例多例是怎么實(shí)現(xiàn)的?
- 4.Bean的后置處理器是怎么實(shí)現(xiàn)的?
- 5.原生Spring的AOP是如何實(shí)現(xiàn)的?
4.將代碼放到遠(yuǎn)程倉(cāng)庫(kù)
- VCS -》 share

- 查看倉(cāng)庫(kù)

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
java實(shí)現(xiàn)excel導(dǎo)入數(shù)據(jù)的工具類
這篇文章主要介紹了java實(shí)現(xiàn)的excel導(dǎo)入數(shù)據(jù)的工具類,需要的朋友可以參考下2014-03-03
詳解IDEA 啟動(dòng)tomcat 端口占用原因以及解決方法( 使用debug模式)
這篇文章主要介紹了詳解IDEA 啟動(dòng)tomcat 端口占用原因以及解決方法( 使用debug模式) ,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來(lái)看看吧2018-08-08
Activiti如何動(dòng)態(tài)獲取流程圖過程詳解
這篇文章主要介紹了Activiti如何動(dòng)態(tài)獲取流程圖過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-03-03
Spring XML Schema擴(kuò)展機(jī)制的使用示例
所謂整合,即在Spring的框架下進(jìn)行擴(kuò)展,讓框架能無(wú)縫的與Spring工程配合使用。Spring設(shè)計(jì)了良好的擴(kuò)展的機(jī)制,本文將對(duì)Spring的擴(kuò)展方法及原理進(jìn)行簡(jiǎn)單介紹。2021-05-05
Maven項(xiàng)目如何查找jar包是由哪個(gè)依賴引入的
這篇文章主要介紹了Maven項(xiàng)目如何查找jar包是由哪個(gè)依賴引入的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08

