您的位置:首页 > 游戏 > 手游 > Spring底层机制环境搭建

Spring底层机制环境搭建

2024/11/17 4:55:13 来源:https://blog.csdn.net/m0_64637029/article/details/141440251  浏览:    关键词:Spring底层机制环境搭建

文章目录

    • 1.模块创建和依赖引入
        • 1.聚合模块,下面有一个myspring
        • 2.查看父模块是否管理了子模块
        • 3.myspring模块引入基本包
    • 2.进行环境搭建
        • 1.目录概览
        • 2.UserController.java
        • 3.UserService.java
        • 4.UserDao.java
        • 5.AppMain.java
        • 6.beans.xml
        • 7.测试
        • 8.配置UserController.java为多例的,然后测试
        • 9.UserService调用add方法,然后测试
        • 10.引入Bean后置处理器
          • 1.位置
          • 2.MyBeanPostProcessor.java
          • 3.UserService.java 设置初始化方法
          • 4.beans.xml配置扫描
          • 5.测试
          • 6.注意事项
        • 11.引入AOP
          • 1.目录
          • 2.SmartAnimal.java
          • 3.SmartDog.java
          • 4.SmartAnimalAspect.java
          • 5.beans.xml开启aop注解并扫描aop包
          • 6.AppMain.java 测试AOP
          • 6.简单分析AOP和后置处理器的关系
    • 3.抛出问题
        • 1.bean是怎么注入容器的?
        • 2.为什么加了@Autowired就能被依赖注入?
        • 3.单例多例是怎么实现的?
        • 4.Bean的后置处理器是怎么实现的?
        • 5.原生Spring的AOP是如何实现的?
    • 4.将代码放到远程仓库
        • 1.VCS -》 share
        • 2.查看仓库

1.模块创建和依赖引入

1.聚合模块,下面有一个myspring

CleanShot 2024-08-04 at 13.50.33@2x

2.查看父模块是否管理了子模块

CleanShot 2024-08-04 at 13.51.05@2x

3.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.进行环境搭建

1.目录概览

CleanShot 2024-08-04 at 14.06.39@2x

2.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 {
}
3.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*/@Autowiredprivate UserDao userDao;public void add() {System.out.println("UserService 调用了UserDao的add方法");userDao.add();}}
4.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...");}}
5.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);}}
6.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>
7.测试

CleanShot 2024-08-04 at 14.09.09@2x

8.配置UserController.java为多例的,然后测试

CleanShot 2024-08-04 at 14.11.14@2x

CleanShot 2024-08-04 at 14.11.24@2x

9.UserService调用add方法,然后测试

CleanShot 2024-08-04 at 14.13.20@2x

CleanShot 2024-08-04 at 14.13.29@2x

10.引入Bean后置处理器
1.位置

CleanShot 2024-08-04 at 14.38.08@2x

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的初始化方法之前执行* @param bean* @param beanName* @return*/@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {// 这里可以提前对bean进行一些处理System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean.getClass());return bean;}/*** 在每个Bean的初始化方法之后执行* @param bean* @param beanName* @return*/@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean.getClass());return bean;}}
3.UserService.java 设置初始化方法

CleanShot 2024-08-04 at 14.38.34@2x

4.beans.xml配置扫描

CleanShot 2024-08-04 at 14.40.15@2x

5.测试

CleanShot 2024-08-04 at 14.40.32@2x

6.注意事项
  • bean的后置处理器在初始化方法调用前后执行
  • 触发时机为单例的第一次getBean和多例的每次getBean,也就是,每个Bean都会经过Bean的后置处理器处理
11.引入AOP
1.目录

CleanShot 2024-08-04 at 15.18.09@2x

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 {@Overridepublic float getSum(float a, float b) {System.out.println("SmartDog...getSum...res=" + (a + b));return a + b;}@Overridepublic 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 // 标注这是一个切面类
public class SmartAnimalAspect {/*** @param joinPoint 保存了要切入的方法的信息* @Before 前置通知* execution(。。。) 切入表达式,表明要切入的方法,格式:格式:访问修饰符+返回类型 全类名 方法名(参数类型)*/@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("方法执行开始-日志-方法名-" + signature.getName()+ "-参数" + Arrays.asList(joinPoint.getArgs()));// 还可以获取目标对象,这样就可以反射进行任何操作了SmartDog target = (SmartDog) joinPoint.getTarget();System.out.println("目标对象-" + 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("方法执行正常结束-日志-方法名-" + 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("方法出现异常-日志-方法名-" + 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("方法最终执行完毕-日志-方法名-" + signature.getName());}/*** 环绕通知* @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("环绕通知 method " + className + "." + methodName);// 获取目标对象Object targetObject = joinPoint.getTarget();// 环绕通知获取目标对象System.out.println("环绕通知获取目标对象:" + targetObject);try {// 前置通知:环绕通知获取参数System.out.println("环绕通知获取参数:" + Arrays.asList(joinPoint.getArgs()));Object result = joinPoint.proceed();  // 执行目标方法// 返回通知:环绕通知获取结果System.out.println("环绕通知获取结果:" + result);return result;} catch (Exception e) {// 异常通知throw e;} finally {// 最终通知System.out.println("环绕通知 method " + className + "." + methodName);}}}
5.beans.xml开启aop注解并扫描aop包

CleanShot 2024-08-04 at 15.19.30@2x

6.AppMain.java 测试AOP

CleanShot 2024-08-04 at 15.19.55@2x

CleanShot 2024-08-04 at 15.27.37@2x

6.简单分析AOP和后置处理器的关系

CleanShot 2024-08-04 at 15.41.14@2x

3.抛出问题

1.bean是怎么注入容器的?
2.为什么加了@Autowired就能被依赖注入?
3.单例多例是怎么实现的?
4.Bean的后置处理器是怎么实现的?
5.原生Spring的AOP是如何实现的?

4.将代码放到远程仓库

1.VCS -》 share

CleanShot 2024-08-04 at 14.44.28@2x

2.查看仓库

CleanShot 2024-08-04 at 14.45.31@2x

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com