java概念理解

内容源自文心一言/网上文摘等,只是记录下来自己的思考和提问,便于自己回顾

Springboot的组件扫描机制是怎么样的?为什么我的filter包是放在Spring Boot主应用程序类所在的包下的,为什么不会被扫描到?
原因:是因为Springboot的扫描机制,只会扫描被Spring框架管理的bean,而filter其实不是属于Springboot的,而是属于javaWeb的,所以你及时放在同级包中也没有用,如果要用就得在Springboot启动类中加上@ServletComponentScan注解,这个注解可以用于自动注册实现了@WebFilter、@WebListener或@WebServlet等Servlet 3.0+规范中定义的注解的组件。

详解:

Spring Boot在启动时,其组件扫描机制默认会扫描主应用程序类(即带有@SpringBootApplication注解的类)所在的包及其子包下的组件。这里的“组件”指的是那些被Spring框架管理的Bean,它们通常是通过@Component、@Service、@Repository、@Controller等注解来标注的Java类。

具体来说,Spring Boot的组件扫描机制如下:

基于主应用程序类的包扫描:
当Spring Boot应用程序启动时,它会从主应用程序类(即带有@SpringBootApplication注解的类)所在的包开始扫描。这个扫描过程会递归地查找该包及其所有子包下的Java类。
识别组件:
在扫描过程中,Spring Boot会查找那些被Spring框架的特定注解(如@Component、@Service、@Repository、@Controller等)标注的类。这些被标注的类会被识别为Spring容器需要管理的Bean。
注册组件:
一旦识别出这些组件,Spring Boot就会将它们注册到Spring的IoC(Inversion of Control,控制反转)容器中。
注册后的组件就可以通过Spring的依赖注入机制(如@Autowired注解)被其他组件使用。
需要注意的是,Spring Boot的组件扫描机制并不是扫描主应用程序类所在包及其子包下的所有Java文件。它只会扫描那些被Spring框架的特定注解标注的Java类,并将它们识别为组件进行注册。其他没有被标注的Java文件则不会被Spring Boot的组件扫描机制识别和处理。

此外,如果需要在主应用程序类所在包之外的其他包中扫描组件,可以使用@ComponentScan注解来指定额外的扫描路径。例如:

java
@SpringBootApplication  
@ComponentScan(basePackages = {"com.example.otherpackage"})  
public class MyApplication {  
    public static void main(String[] args) {  
        SpringApplication.run(MyApplication.class, args);  
    }  
}
在这个例子中,@ComponentScan注解指定了除了主应用程序类所在包之外,还需要扫描com.example.otherpackage包下的组件。

为什么请求都会经过Filter?是协议规定的吗?
当你是一个Web应用程序,那就有它的规则。客户端,服务端。请求与响应。

详解:

请求会经过Filter并不是由协议直接规定的,而是由Web应用架构和Filter在其中的角色所决定的。具体来说,Filter在Web应用中起着拦截和处理请求与响应的作用,其原理基于责任链模式。以下是关于为什么请求会经过Filter的详细解释:

Filter的作用:
Filter是Java Web应用中一种常用的组件,用于在请求和响应之间进行拦截和处理。通过在请求链和响应链中插入自定义的过滤器,可以对请求和响应进行各种操作,如日志记录、身份验证、授权、数据转换等。
Filter的执行流程:
当一个请求到达服务器时,它首先会经过Web容器(如Tomcat)。
Web容器会根据请求的URL匹配到对应的Servlet或JSP进行处理。
在这个过程中,Filter会被依次执行。Filter的执行顺序是由部署描述符(web.xml)中的配置决定的。
Filter的配置:
在web.xml中,我们可以为Filter配置<filter><filter-mapping>元素。
<filter>元素用于定义Filter的名称和类路径。
<filter-mapping>元素用于配置Filter的拦截路径。当请求到达时,Web容器会根据这些配置找到匹配的Filter并执行。
Filter与协议的关系:
虽然HTTP协议定义了Web客户端和服务器之间如何通信,但它并没有规定请求必须经过Filter。
Filter是Web应用架构中的一个组件,用于在Web容器内部对请求和响应进行额外的处理。
因此,请求会经过Filter是由Web应用架构和Filter的角色所决定的,而不是由协议直接规定的。
总结来说,请求会经过Filter是因为Filter在Web应用架构中扮演着拦截和处理请求与响应的角色。虽然这不是由HTTP协议直接规定的,但它是Web应用开发中的一种常见做法,用于实现各种功能需求。

什么是链式编程,在学习JWT令牌技术的时候接触到这个写法,记录一下!
原写法:

@Test
public void testGenJwt(){
    Map<String, Object> claims = new HashMap<>();
    claims.put("id",1);
    claims.put("name","tom");

    String jwt = Jwts.builder()
            .signWith(SignatureAlgorithm.HS256, "itheima")//签名算法
            .setClaims(claims) //自定义内容(载荷)
            .setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000))//设置有效期为1h
            .compact();
    System.out.println(jwt);
}

详解:

链式编程(Chaining Programming),也被称为链式调用或流式编程,是一种编程风格,旨在提高代码的流畅性和简洁性。以下是关于链式编程的详细解释:

定义与概念:
链式编程允许通过点号(.)将多个方法或函数连续调用,而无需在每次调用后都重新引用对象本身。
每个方法调用后返回一个对象或实例,使得可以继续在该对象或实例上调用其他方法,从而形成一条调用链。
核心思想:
每个被调用的方法都需要返回调用它的对象本身(通常是通过返回this指针或当前对象实例),以实现链式调用。
这种编程风格的主要目的是减少代码的冗余,提高代码的可读性和可维护性。
示例:
以Java中的StringBuffer为例,它就是一个典型的链式编程实现。通过连续调用append()方法,可以不断地向StringBuffer中添加内容,而无需每次都重新创建新的StringBuffer对象。
另一个示例是自定义一个StudentBean类,其中setName()setAge()方法都返回this指针,从而允许链式调用,如new StudentBean().setAge(22).setName("ly")。
优势:
代码更加简洁和流畅,减少了冗余和复杂性。
提高了代码的可读性,使得代码更易于理解和维护。
在某些情况下,链式编程可以提高代码的执行效率,因为它减少了对象的创建和销毁次数。
注意事项:
虽然链式编程带来了很多好处,但过度使用也可能导致代码难以理解和维护。因此,在使用链式编程时需要根据实际情况进行权衡和选择。
链式编程通常适用于那些需要连续设置多个属性的场景,如配置对象或构建复杂的数据结构等。
总之,链式编程是一种强大的编程风格,通过连续调用方法并返回对象本身来实现代码的简洁和流畅。在实际开发中,可以根据项目需求选择是否使用链式编程来提高代码质量。 

什么是面向接口编程?

  • 思考:以前单机的时候,考虑功能很简单,能实现就行。例如要支付,可能有多种支付方式。那就写一个支付类,然后里面创建各种各样的支付方法(支付宝、微信等等),但是业务一变,我就又得修改源代码,增加新的方法。但是面向接口就有这好处,利用多态,子类继承父类的方法,然后使用父类来引用子类,具体的实现交给具体的子类(把功能抽象出来,具体怎么实现交给子类)
  • 详解:
好的,以下是一个简单的面向接口编程的例子。

假设我们要设计一个系统,这个系统可以处理不同的支付方式,比如信用卡支付、支付宝支付等。为了遵循面向接口编程的原则,我们可以首先定义一个支付接口,然后为每种支付方式创建一个实现类。

首先,我们定义一个名为Payment的接口:
public interface Payment {  
    void pay(double amount);  
}
这个接口定义了一个pay方法,它接受一个金额参数。接下来,我们为每种支付方式创建一个实现类。首先是信用卡支付:

public class CreditCardPayment implements Payment {  
    @Override  
    public void pay(double amount) {  
        System.out.println("Paying " + amount + " with credit card.");  
        // 具体的支付逻辑  
    }  
}
然后是支付宝支付:
public class AliPay implements Payment {  
    @Override  
    public void pay(double amount) {  
        System.out.println("Paying " + amount + " with AliPay.");  
        // 具体的支付逻辑  
    }  
}
现在,我们的系统可以很容易地支持新的支付方式,只需要创建一个新的类并实现Payment接口即可。
在主程序中,我们可以这样使用这些支付方式:
public class Main {  
    public static void main(String[] args) {  
        Payment creditCardPayment = new CreditCardPayment();  
        creditCardPayment.pay(100.0);  
          
        Payment aliPay = new AliPay();  
        aliPay.pay(200.0);  
    }  
}
这个例子展示了面向接口编程的核心思想:定义接口来抽象功能,然后创建实现这些功能的类。这样做的好处是,当需要添加新的支付方式时,只需要创建一个新的类并实现相应的接口,而不需要修改现有的代码。这大大提高了代码的可扩展性和可维护性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值