当前位置: 代码网 > it编程>编程语言>Java > Spring底层机制环境搭建全过程

Spring底层机制环境搭建全过程

2024年12月10日 Java 我要评论
spring底层机制环境搭建1.模块创建和依赖引入聚合模块,下面有一个myspring查看父模块是否管理了子模块myspring模块引入基本包<dependencies> <d

spring底层机制环境搭建

1.模块创建和依赖引入

聚合模块,下面有一个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.进行环境搭建

目录概览

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 调用了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调用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的初始化方法之前执行
     * @param bean
     * @param beanname
     * @return
     */
    @override
    public object postprocessbeforeinitialization(object bean, string beanname) {
        // 这里可以提前对bean进行一些处理
        system.out.println("postprocessbeforeinitialization..."+beanname+"=>"+bean.getclass());
        return bean;
    }

    /**
     * 在每个bean的初始化方法之后执行
     * @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 设置初始化方法

4.beans.xml配置扫描

5.测试

6.注意事项

  • bean的后置处理器在初始化方法调用前后执行
  • 触发时机为单例的第一次getbean和多例的每次getbean,也就是,每个bean都会经过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 // 标注这是一个切面类
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包

6.appmain.java 测试aop

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

3.抛出问题

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

4.将代码放到远程仓库

  • vcs -》 share

  • 查看仓库

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com