spring学习 【基础】

news2024/11/15 9:09:37

目录

1.将bean交给spring容器管理

1. 编写bean对象

2. 在resources目录下创建spring config xml文件,并管理bean对象

3. spring容器管理工厂

2.Spring Bean 生命周期

2.1 Spring Bean初始化方法 

2.1.1 自定义初始化方法

2.1.2  实现接口(InitializingBean)初始化方法

2.2 Spring Bean 销毁方法

2.2.1 自定义方式销毁

2.2.2  实现DisposableBean接口方式

2.3 Spring Bean 后置处理器

2.3.1 创建一个类(Myprocessor)并实现BeanPoscessor接口

2.3.2 创建一个类(StudentService),并实现InitializingBean接口,使用初始化方法

2.3.3  编写spring配置文件(applicationContext.xml),配置后置处理器,并管理StudentService

2.3.4 最后执行结果

3.Ico(控制反转)

3.1 依赖注入bean的两种方式

3.1.1通过构造的方式注入

3.1.2 通过setter方式注入

3.2 依赖注入注入值

3.2.1 通过构造方式注入属性 

3.2.2 通过setter方式注入属性

​编辑 3.2.3 注入map属性

3.2.4 注入list属性

4. 注解

4.1 @Component注解

4.2 MVC三大注解(@Controller、@Service、@Repository)

4.3 @Scope注解

4.4 生命周期注解(@PostConstruct、@PoreDestory)

4.4.1 在pom文件中配置javax依赖

4.4.2 @PostConstruct注解(bean初始化)

4.4.3 @PreDestory注解(bean销毁)

4.5 依赖注入注解(@Inject、@Named)

4.6@Resource注解

4.7 @Autowired注解、@Qualifier

4.8 @RequiredArgsConstructor 注解


 

1.将bean交给spring容器管理

1.为什么要将bean交给spring容器管理?

                在没有spring之前,我们需要某个对象时,是通过手动new创建出来对象的,这样手动创建出来的方式具有强耦合的关系,如果在bean对象中需要依赖另一个bean对象时,当被依赖的对象需要做出改变时,需要依赖对象的一方则也要做出想对应的改变


比如 如果被依赖的一方改了名称,则需要依赖的一方也要更改,则间接违反了开闭原则


现在将bean对象交给spring容器管理,则不需要我们手动创建bean对象,Spring容器负责自动创建和注入这些依赖,这就实现了spring中的思想控制反转 


所谓控制反转,就是对象不再主动获取依赖(例如通过new关键字创建依赖对象),而是由外部容器负责注入依赖给它。当需要对象时,通过容器取获取即可

1. 编写bean对象

1.1 编写UserService接口

public interface UserService {
    /**
     * 添加用户
     */
    void addUser();
}

1.2 编写类对象实现UserService接口

public class UserServiceImpl implements UserService {
    @Override
    public void addUser() {
        System.out.println("添加用户");
    }
}
public class TeacherServiceImpl implements UserService {
    @Override
    public void addUser() {
        System.out.println("创建老师");
    }
}

2. 在resources目录下创建spring config xml文件,并管理bean对象

定义名为beans.xml的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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--装配UserService实现类-->
    <!--id表示这个bean在容器里面的唯一表示-->
    <!--class表示bean的完整类名-->
    <bean id="userService" class="com.xr.springdemo.service.impl.UserServiceImpl"/>

    <bean id="studentService" class="com.xr.springdemo.service.impl.TeacherServiceImpl"/>


</beans>

现在我们创建的bean对象都以及交给spring容器管理了

2.1  通过配置文件初始化容器工厂,并通过工厂来获取bean对象

创建一个main方法

public class Main {
    public static void main(String[] args) throws BeansException {

        // 根据配置文件初始化一个容器工厂,并关联xml文件
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        // 从容器中获取bean对象(根据xml文件配置bean中的唯一id来获取)
         UserService userService = (UserService) context.getBean("userService");
         UserService teacherService = (UserService) context.getBean("teacherService");

         // 调用
         userService.addUser();
         teacherService.addUser();
    }
}

最后执行结果

现在我们获取bean对象的方式并不是通过new的方式,而是通过spring容器获取到的bean对象


3. spring容器管理工厂

spring容器不仅可以管理bean对象,还可以将自定义工厂交给spring容器管理,而定义工厂生产出来的bean对象也会被spring容器管理,所以spring容器非常灵活

3.1 创建自定义静态工厂 (StudentServiceFactory)

/**
 * 自定义工厂来创建特定的对象
 * 这个自定义工厂也将纳入spring容器中
 * spring会调用自定义工厂的方法来创建Bean对象
 * 创建出来的bean也会纳入容器中管理
 */
public class StudentServiceFactory {
    public static UserService create() {
        return new StudentServiceImpl();
    }
}

3.2 将自定义静态工厂交给spring容器管理,而自定义工厂创建出来的bean对象也会被spring容器管理

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--装配UserService实现类-->
    <!--id表示这个bean在容器里面的唯一表示-->
    <!--class表示bean的完整类名-->
    <bean id="userService" class="com.xr.springdemo.service.impl.UserServiceImpl"/>
    <bean id="studentService" class="com.xr.springdemo.service.impl.TeacherServiceImpl"/>



    <!--装配自定义工厂,由spring容器来管理这个工厂,factory-method指定自定义静态工厂的方法-->
    <bean id="studentService" class="com.xr.springdemo.factory.StudentServiceFactory" factory-method="create"/>


</beans>

3.3 通过自定义工厂获取Bean对象

public class Main {
    public static void main(String[] args) throws BeansException {

        // 根据配置文件初始化一个容器工厂,并关联xml文件
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        // 通过自定义工厂创建的bean对象,并获取
        UserService studentService = (UserService) context.getBean("studentService");
        // 调用方法
        studentService.addUser();
    }
}

最后执行结果

                发现spring容器将自定义工厂创建出来的bean对象也管理了起来

3.4 基于spring提供的FactoryBean接口创建工厂,官方推荐

/**
 * 自定义工厂,这个工厂是实现spring提供的FactoryBean接口
 */
public class TeacherServiceFactoryBean implements FactoryBean<UserService> {

    /**
     * getObject方法创建一个对象
     */
    @Override
    public UserService getObject() throws Exception {
        return new TeacherServiceImpl();
    }

    /**
     * getObjectType方法返回创建对象的类型
     */
    @Override
    public Class<?> getObjectType() {
        return TeacherServiceImpl.class;
    }
}

3.5 创建TeacherServiceImpl类并实现UserService 

public class TeacherServiceImpl implements UserService {
    @Override
    public void addUser() {
        System.out.println("创建老师");
    }
}

3.6 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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--装配UserService实现类-->
    <!--id表示这个bean在容器里面的唯一表示-->
    <!--class表示bean的完整类名-->
    <bean id="userService" class="com.xr.springdemo.service.impl.UserServiceImpl"/>
    <bean id="studentService" class="com.xr.springdemo.service.impl.TeacherServiceImpl"/>



    <!--装配自定义工厂,由spring容器来管理这个工厂,factory-method指定自定义静态工厂的方法-->
    <bean id="studentService" class="com.xr.springdemo.factory.StudentServiceFactory" factory-method="create"/>

    <!--装配实现Spring提供FactoryBean接口的工厂-->
    <bean id="teacherService" class="com.xr.springdemo.factory.TeacherServiceFactoryBean"/>


</beans>

3.6 获取bean对象并执行

public class Main {
    public static void main(String[] args) throws BeansException {
        // 根据配置文件初始化一个容器工厂
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserService teacherService = (UserService) context.getBean("teacherService");
        teacherService.addUser();
    }
}

最后执行结果

这种方式是通过spring提供factoryBean接口的方式创建的工厂并交给spring容器进行管理

2.Spring Bean 生命周期

  • 对象构造方法

    • Spring 通过反射机制调用 Bean 的构造方法,创建 Bean 的实例。此时,Bean 还没有完成属性的注入。
    • 例如:new UserService(),调用无参构造器。
  • 后置处理器的 postProcessBeforeInitialization 方法

    • 在 Bean 初始化之前,Spring 调用实现了 BeanPostProcessor 接口的后置处理器的 postProcessBeforeInitialization 方法。
    • 这个方法可以对 Bean 进行预处理,在 Bean 完成初始化前做一些自定义操作。
    • 对应配置中的 <bean id="myProcessor" class="com.xr.processor.MyProcessor"/>
  • InitializingBean 接口的 afterPropertiesSet 方法

    • 如果 Bean 实现了 InitializingBean 接口,Spring 会调用其 afterPropertiesSet 方法进行初始化操作。
    • 这个方法是 Spring 内置的初始化回调机制之一,用于在所有的属性被设置后执行一些定制的初始化逻辑。
  • 自定义的 init-method 初始化方法

    • 如果在 XML 配置中指定了 init-method 属性,Spring 会调用指定的初始化方法。在配置中,UserService Bean 使用了 beanInit 作为自定义初始化方法。
    • 这是另一种初始化 Bean 的方式。
  • 后置处理器的 postProcessAfterInitialization 方法

    • 在 Bean 初始化之后,Spring 调用实现了 BeanPostProcessor 接口的后置处理器的 postProcessAfterInitialization 方法。
    • 这个方法可以对 Bean 进行后处理操作,在 Bean 初始化完成后做进一步定制化处理。
  • DisposableBean 接口的 destroy 方法

    • 如果 Bean 实现了 DisposableBean 接口,Spring 在销毁 Bean 时会调用其 destroy 方法。
    • 这个方法是 Spring 提供的内置销毁回调,用于 Bean 在被销毁之前执行清理操作。
  • 自定义的 destroy-method 销毁方法

    • 如果在 XML 配置中指定了 destroy-method 属性,Spring 在 Bean 被销毁时会调用这个方法。在配置中,UserService Bean 使用了 beanDestroy 作为自定义销毁方法。
    • 这是另一种销毁 Bean 的方式。

spring Bean先销毁,在着是spring容器销毁

后置处理器(BeanPostProcessor) 是 Spring 框架中一个重要的扩展机制,它允许在 Spring 容器实例化 Bean 之后、初始化方法执行前后对容器中所有 Bean 进行一些自定义的修改或增强。

执行顺序:

        bean对象的构造方法--------------------》》》后置处理器postProcessBeforeInitialization---------------》》》InitializingBean 接口的 afterPropertiesSet bean初始化方法---------------------》》》自定义的 init-method 初始化方法----------------------------------》》》后置处理器的 postProcessAfterInitialization 方法-----------------------------》》》DisposableBean 接口的 destroy 销毁方法----------------------》》》自定义的 destroy-method 销毁方法


初始化方法和销毁方法有两种一个是实现接口,一个是自定义方法,如果两种同时使用,优先执行实现接口的方法,在执行自定义方法

2.1 Spring Bean初始化方法 

2.1.1 自定义初始化方法

2.1.1.1 创建UserService类,并编写构造方法和自定义初始化方法

public class UserService {

    /**
     * 构造方法是被JVM在创建类实例的时候自动调用
     * 例如:new UserService();
     * 或者基于反射创建 USerService.class.newInstance();
     */
    public UserService() {
        System.out.println("执行UserService构造方法");
    }


    /**
     * 自定义Bean的初始化方法
     */
    public void beanInit() {
        System.out.println("执行Bean的初始化方法");
    }
}

2.1.1.2 将UserService Bean交给spring容器 管理,编写名为applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--bean初始化方法:
        两种方式:
        第一种方式. 在Bean中自定义初始化方法,在配置中使用init-method属性来指定初始化方法-->
    <bean id="userService" class="com.xr.service.UserService" init-method="beanInit"/>
   
</beans>

 在自定义初始化方式,将Bean交给spring 容器管理的时候需要使用init-method属性来指定初始化方法

2.1.1.3 编写Main方法

public class Main {
    public static void main(String[] args) {
        // 创建spring上下文,从而通过它来访问和操作在Spring配置文件(applicationContext.xml)中定义的bean对象
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

    }
}

执行结果:   

 Main方法 中只是获取了spring上下文,没有调用构造方法和自定义初始化方法,执行的结果却调用了先执行了构造方法在执行自定义初始化方法

构造方法:           由jvm创建

初始化方法:        由spring容器创建

所有Bean对象一开始都是交由spring容器进行管理,所以只要spring容器一开始则就会调用所有bean对象的初始化方法,而构造方法确实jvm创建

2.1.2  实现接口(InitializingBean)初始化方法

2.1.2.1 创建StudenttService类,并实现InitializingBean接口

public class StudentService implements InitializingBean {

    public StudentService() {
        System.out.println("执行StudentService的构造方法");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("实现了initializingBean接口,执行studnetafterPropertiesSet方法");
    }
}

2.1.2.2 将StudentService Bean交给spring容器 管理,在applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--bean初始化方法:
        两种方式:
        第二种方式. 在Bean中实现InitializingBean接口,接口中包含一个afterPropertiesSet方法-->
    <bean id="userService" class="com.xr.service.UserService"/>
   
</beans>

2.1.2.3 编写Main方法

public class Main {
    public static void main(String[] args) {
        // 创建spring上下文,从而通过它来访问和操作在Spring配置文件(applicationContext.xml)中定义的bean对象
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

    }
}

2.1.2.4  执行结果

2.2 Spring Bean 销毁方法

有初始化那么就肯定有销毁,那么spring Bean销毁的方式有两种

                1. 自定义销毁方式

                2. 实现DisposableBean接口的方式

2.2.1 自定义方式销毁

2.2.1.1 创建一个UserService类,并编写一个销毁bean方法

public class UserService implements DisposableBean {
    /**
    * 自定义销毁方法
    */
    public void beanDestroy() {
        System.out.println("准备销毁Bean");
    }
}
        

2.2.1.2 在spring配置文件中(applicationContext.xml)装配该bean对象,并使用destory-method属性指定销毁方法的名称

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--
        bean的第一种销毁方法:
            1. 在Bean方法中自定义销毁方法,在配置中使用destroy-method属性来指定销毁方法
    -->
<bean id="userService" class="com.xr.service.UserService" destroy-method="beanDestroy"/>
</beans>

 2.2.1.3 编写Main方法

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        /**
         * 关闭容器,关闭才勾起相关的销毁方法
         * 如果不关闭容器,那么销毁方法是不会执行的
         * 关闭容器之前,bean的销毁方法比关闭容器先执行,bean销毁完成之后容器才会关闭
         */
        ((ClassPathXmlApplicationContext)context).close();
    }
}

2.2.1.4 最后执行结果为

2.2.2  实现DisposableBean接口方式

2.2.2.1 定义StudentService类实现DisposableBean接口,并重写destory方法

public class StudentService implements DisposableBean{

    @Override
    public void destory() thorw Exception() {
        System.out.println("实现类DisposableBean接口,并重写了销毁方法,执行销毁");
    }
}

2.2.2.2 在spring配置文件中(applicationContext.xml)装配该bean对象,无需使用destory-method属性指定销毁方法的名称

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--
        bean的第二种销毁方法:
            1. 在Bean中实现DisposableBean接口,接口中包含一个destroy方法
    -->
<bean id="userService" class="com.xr.service.UserService"/>
</beans>

2.2.2.3 编写main方法

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        /**
         * 关闭容器,关闭才勾起相关的销毁方法
         * 如果不关闭容器,那么销毁方法是不会执行的
         * 关闭容器之前,bean的销毁方法比关闭容器先执行,bean销毁完成之后容器才会关闭
         */
        ((ClassPathXmlApplicationContext)context).close();
    }
}

2.2.2.4执行结果为:

如果实现接口的方式和自定义的方式同时使用,优先执行实现接口的方式 

2.3 Spring Bean 后置处理器

                它是一种允许在 Spring 容器中创建 Bean(Java 对象)之前或之后对 Bean 进行额外处理的接口。Spring 框架利用后置处理器来实现各种功能,比如为 Bean 进行自动注入、代理增强等操作


简要的说:

        就是在bean初始化之前和初始化之后可以做一些事情

2.3.1 创建一个类(Myprocessor)并实现BeanPoscessor接口


/**
 * Bean的后置处理器(必须实现BeanPostProcessor)
 * 后置处理器可以将spring容器装配完Bean之后(包括依赖注入)
 * 在执行Bean的初始化方法之前执行(afterPropertiesSet、init-method)前后执行
 * 也就是在初始化方法前执行后置处理器的postProcessBeforeInitialization方法
 * 在初始化方法后执行后置处理器的postProcessAfterInitialization方法
 */
public class MyProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("执行后置处理器postProcessBeforeInitialization方法,在所有Bean的初始化之前执行,每个bean初始化之前都会执行");
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("执行后置处理器postProcessAfterInitialization方法,在所有Bean的初始化之后执行,每个bean初始化之后都会执行");
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
}

2.3.2 创建一个类(StudentService),并实现InitializingBean接口,使用初始化方法

public class StudentService implements InitializingBean {

    public StudentService() {
        System.out.println("执行StudentService的构造方法");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("bean的初始化,实现了initializingBean接口,执行studnetafterPropertiesSet方法");
    }
}

2.3.3  编写spring配置文件(applicationContext.xml),配置后置处理器,并管理StudentService

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--配置bean对象-->
    <bean id="studentService" class="com.xr.service.StudentService" />
    <!--装配后置处理器-->
    <bean id="myProcessor" class="com.xr.processor.MyProcessor"/>

</bean>

2.3.4 最后执行结果

3.Ico(控制反转)

不是什么技术,而是一种设计思想。在Java开发中,Ioc意味着将你设计好的对象交给容器控制,而不是传统的在你的对象内部直接控制。


什么是控制反转:

        容器将底层模板反向注入到高层模块的过程,间接实现了依赖倒置原则


一开始我们需要某对象都是使用new关键字获取的,现在我们是通过spring容器获取

3.1 依赖注入bean的两种方式

3.1.1.2  先创建controller,service包,并在controller包下创建UserController,在到service创建userService接口和一个子包impl,最后到impl下创建UserServiceImpl并实现userService接口


当我想使用UserServsice实现类的时候,通常时直接在UserController类中创建出来

如:

        UserService userService = new UserServiceImpl();

但是我们现在通过容器取获取,将创建对象的主动权交给容器取做,我们直接获取就ok了

UserService接口

public interface UserService {
    void add ();
}

 UserServiceImpl类实现UserService接口

public class UserServiceImpl implements UserService {


    @Override
    public void add() {
        System.out.println("添加用户");
    }
}

3.1.1通过构造的方式注入

通过依赖注入获取bean的第一中方式

UserController类

public class UserController {
    /**
     *  需要依赖的UserService接口
     */
    private UserService userService;


    /**
     * 1. 方式一通过构造器的方式获取bean对象
     * 2.将UserService的实现类注入进来
     */
    public UserController(UserService userService) {
        this.userService = userService;
    }
    

    // 调用userService接口实现的add方法
    public void add() {
        userService.add();
    }
}

 spring配置(applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--将userService注入到userController中,通过构造方法注入-->

    <!--
        name对应构造方法的参数名称,
        type指定参数的类型,
        index指定参数的下标
        所以name、type、index三者都可以指定参数的方式
        ref同样是引用容器中Bean的id,
        这里我们需要在userController对象中注入的对象是下面的userService

        这些都是constructor-arg标签的属性,都是用来指定依赖的bean对象的,选一即可
    -->

    <!--首先将两个bean对象都交给spring容器管理(userController,userService)-->
    <bean id="userController" class="com.xr.controller.UserController">
        <!--将下面的userService对象注入到userController中-->
        <constructor-arg ref="userService"/>
    </bean>

    
    <bean id="userService" class="com.xxr.service.impl.userService"/>

    
</beans>

编写mian方法

public class Main {
    public static void main(String[] args) {
        // 容器将低层模板反向注入到高层模块的过程
        ApplicationContext application = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserController bean = application.getBean(UserController.class);
        bean.add();
    }
}

最后执行结果

发现:

        我们在userController中并没有使用new关键字创建出userService对象,而是通过构造器的方式结合spring的xml配置文件配置来获取的bean对象 

3.1.2 通过setter方式注入

userController类

/**
 * 通过setter注入
 * 通过构造器注入
 */
public class UserController {
    
    private UserService userService;

    /**
     * 将UserService的实现类注入进来
     */
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public void add() {
        userService.add();
    }
}

  spring配置(applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--将userService注入到userController中,通过构造方法注入-->

    <!--
        name对应构造方法的参数名称,
        type指定参数的类型,
        index指定参数的下标
        所以name、type、index三者都可以指定参数的方式
        ref同样是引用容器中Bean的id
    -->
    <bean id="userController" class="com.xr.controller.UserController">
        <!--name对应的是set注入方法,将set去掉然后将set后面的第一个字母改成小写,
       ref属性值表示引用容器中bean的id,就是你要依赖哪个对象就引用谁的bean-->
        <property name="userService" ref="userService"/>
    </bean>


    <bean id="userService" class="com.xr.service.impl.UserServiceImpl"/>

</beans>

 编写main方法

public class Main {
    public static void main(String[] args) {
        // 容器将低层模板反向注入到高层模块的过程
        ApplicationContext application = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserController bean = application.getBean(UserController.class);
        bean.add();
    }
}

执行结果

构造注入和setter方法注入都可以获取想要的依赖,二选一即可

3.2 依赖注入注入值

spring不仅可以注入对象依赖还可以注入属性

3.2.1 通过构造方式注入属性 

创建一个UserService类,并定义两个属性(name,age)通过构造方法的方式注入

public class UserService {

    /**
     * 定义两个属性
     */
    private String name;
    private Integer age;

    /**
     * 定义有参构造方法
     */
    public UserService(String name,Integer age)
    {
        this.name = name;
        this.age = age;
    }


    /**
     * 最后输出属性
     */
    public void say() {
        System.out.println("name:"+name+" age:"+age);
    }
}

编写spring配置文件(applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="userService" class="com.xr.service.UserService">
        <!--name指定的是属性的名称,value是属性的值-->
        <constructor-arg name="name" value="张三"/>
        <constructor-arg name="age" value="18"/>
    </bean>
</beans>

编写mian方法

public class Main {
    public static void main(String[] args) {
        ApplicationContext application = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService bean = application.getBean(UserService.class);
        // 调用输出方法
        bean.say();
    }
}

最后执行结果

 

3.2.2 通过setter方式注入属性

编写userService类

package com.xr.service;

import java.util.List;

public class UserService {
    // 定义两个属性
    private String name;
    private Integer age;

    // 定义set方法
    public void setName(String name) {
        this.name = name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    // 输出方法
    public void say() {
        System.out.println("name:"+name+" age:"+age);
    }
}

编写spring配置文件(applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="userService" class="com.xr.service.UserService">
        <property name="name" value="小明"/>
        <property name="age" value="18"/>
    </bean>
</beans>

 编写main方法

public class Main {
    public static void main(String[] args) {
        ApplicationContext application = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService bean = application.getBean(UserService.class);
        // 调用输出方法
        bean.say();
    }
}

最后执行结果

 3.2.3 注入map属性

编写userService类

public class UserService {
    private Map<String, String> addresses;

    //方式一:通过构造方式注入
    public UserService(Map<String,String> addresses) {
        this.addresses = addresses;
    }

    // 方式二:通过set方法注入
    public void setAddresses(Map<String, String> addresses) {
        this.addresses = addresses;
    }



    // 最后输出语句
    public void say() {
        System.out.println(addresses);
    }


    /*两种方式二选一即可*/
}

编写spring配置文件(applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="userService" class="com.xr.service.UserService">
        <!--两种方式二选一即可-->
        <!--通过构造注入map方法-->
        <constructor-arg>
            <map>
                <entry key="1" value="北京"/>
                <entry key="2" value="上海"/>
            </map>
        </constructor-arg>

        <!--通过set 注入map方法-->
        <property name="addresses">
            <map>
                <entry key="1" value="北京"/>
                <entry key="2" value="上海"/>
            </map>
        </property>
    </bean>
</beans>

 编写main方法

public class Main {
    public static void main(String[] args) {
        ApplicationContext application = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService bean = application.getBean(UserService.class);
        // 调用输出方法
        bean.say();
    }
}

最后执行结果

3.2.4 注入list属性

编写userService类

package com.xr.service;

import java.util.List;

public class UserService {
    // 定义list集合
    private List<String> addresses;

    // 方式一:通过构造方式注入
    public UserService(List<String> addresses) {
        this.addresses= addresses;
    }

    // 方式二: 通过set方式注入
    public void setAddresses(List<String> addresses) {
        this.addresses = addresses;
    }


    public void say() {
        System.out.println(addresses);
    }
}

 编写spring配置文件(applicationContext.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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="userService" class="com.xr.service.UserService">
        <!--二选一即可-->
        <!--方式一:通过构造注入list集合-->
        <constructor-arg name="addresses">
            <list>
                <value>南美</value>
                <value>非洲</value>
            </list>
        </constructor-arg>
        
        <!--通过set注入list集合-->
        <property name="addresses">
            <list>
                <value>北京</value>
                <value>上海</value>
            </list>
        </property>
    </bean>
</beans>

 编写main方法

package com.xr;

import com.xr.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {
    public static void main(String[] args) {
        ApplicationContext application = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService bean = application.getBean(UserService.class);
        // 调用输出方法
        bean.say();
    }
}

最后执行结果

4. 注解

上面配置了一大堆的东西是不是非常繁琐,注解就是简化了这些配置来达到快速编写代码,简便了在applicationContext.xml文件配置

首先在applicationContext.xml配置扫描注解的基础配置

1.如果想要使用注解则必须要编写扫描注解配置

<?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">

    <!--1.启用注解处理器,这样才可以使用spring提供的注解来配置-->
    <context:annotation-config/>
    <!--2.配置扫描,将带有注解的类交给spring管理
        当撇脂component-scan时,默认就会启用注解处理器,所以可以不用配置注解处理器-->
    <context:component-scan base-package="com.xr.zhujie"/>
</beans>

4.1 @Component注解

@Component 是 Spring 框架中的一个通用注解,用于将类标识为 Spring 管理的组件(即 Bean)。


 标注在类上面,表示当前类将纳入容器管理,去掉xml中的<bean/>标签的配置


 注解中的value属性表示在容器中的唯一标识,想当于xml中<bean/>标签id属性


简化了在xml配置bean的操作

定义一个UserController类,并在该类中标明@Component注解

/**
 * 使用Component标注,表示该类由spring容器管理,想当于xml中<bean/> 标签
 * 注解值表示在spring容器的唯一标识,相当于xml中<bean/>标签的id属性
 */
@Component("userController")
public class UserController {

    public void say(){
        System.out.println("使用了Component注解,将该类交给了spring容器管理");
    }
}

4.2 MVC三大注解(@Controller、@Service、@Repository)

Spring 还提供了三个针对不同层次的特定注解,它们都是 @Component 的特殊化形式


  • @Controller:用于表示控制层组件,处理用户请求和响应。
  • @Service:用于表示服务层组件,承载业务逻辑。
  • @Repository:用于表示持久层组件,负责数据持久化操作。

这三个注解标注在不同层上,和@Component具有相同的效果,额外增加了细化语义效果 

创建三个包(controller,service,dao),在这三个包下分别创建3个类(userController,userService,userDao)

userController类(@Controller层)

/**
 * 表示这是控制层
 */
@Controller
public class userController {

    public void say() {
        System.out.println("使用@Controller注解标注类上,可以不使用@Component注解,表示这是控制层,用于接收请求,返回响应");
    }
}

 userService类(@Service)

/**
 * 表示这是服务层
 */
@Service
public class userController {

    public void say() {
        System.out.println("使用@Service注解标注类上,可以不使用@Component注解,表示这是服务层,用于处理业务逻辑");
    }
}

userDao类(@Repository )

/**
 * 表示这是持久层
 */
@Repository
public class userController {

    public void say() {
        System.out.println("使用@Repositroy注解标注类上,可以不使用@Component注解,表示这是数据持久层,用于将数据持久化到数据库");
    }
}

4.3 @Scope注解

@Scope 是 Spring 框架中用于指定 Bean 作用域的注解。通过使用 @Scope,开发者可以控制 Spring 容器如何创建和管理 Bean 的实例,从而满足不同的需求


默认为单例,不写注解值为单例,指定值为prototype就是原型(多例)

创建UserService类

@Scope("prototype")
public class UserService{

    public void say() {
        System.out.println("使用Scope注解,指定注解值为prototype,该类为原型,既多例,不写注解值为单例");
    }
}

4.4 生命周期注解(@PostConstruct、@PoreDestory)

@PostConstruct@PreDestroy 是 Java 标准中的注解,定义在 javax.annotation 包中。这两个注解用于在 Bean 的生命周期中执行特定的方法:

  • @PostConstruct:在 Bean 完成依赖注入后、初始化方法执行前调用,用于进行初始化操作。
  • @PreDestroy:在 Bean 销毁之前调用,用于进行资源释放等清理操作。

因为他是外部依赖,所以需要到pom.xml引用javax的依赖


原型创建的Bean时不会执行销毁方法的,因为创建的对象不受容器管理,Scope指定为prototype,就是临时对象

4.4.1 在pom文件中配置javax依赖

        <!--要使用生命周期的注解时需要导入此包-->
        <dependency>
            <groupId>javax.annotation</groupId>
            <artifactId>javax.annotation-api</artifactId>
            <version>1.3.2</version>
        </dependency>

4.4.2 @PostConstruct注解(bean初始化)

@PostConstruct相当上面生命周期中2.1.1和2.1.2的两个案例

创建一个UserController类

@Controller
public void UserController {

    /**
     * 等价于xml中init-method属性
     */
    @PostConstruct
    public void init() {
        System.out.println("bean的初始化,当一启动,构造方法先执行,在执行该方法");
    }
}

编写Main方法

public class Main {
    public static void main(String[] args) {
        ApplicationContext ctx =  new ClassPathXmlApplicationContext("applicationContext.xml");
}

执行结果

4.4.3 @PreDestory注解(bean销毁)

 @PreDestory相当上面生命周期中2.2.1和2.2.2的两个案例


@PreDestory注解等价xml中destory-method属性


原型创建的Bean时不会执行销毁方法的,因为创建的对象不受容器管理,Scope指定为prototype,就是临时对象(也就是多例)

在UserController类基础上增加destory()方法

@Controller
public void UserController {

    /**
     * 等价于xml中init-method属性
     */
    @PostConstruct
    public void init() {
        System.out.println("bean的初始化,当一启动,构造方法先执行,在执行该方法");
    }

    /**
     * @PreDestroy等价于destroy-method
     */
    @PreDestroy
    public void destory() {
        System.out.println("bean销毁,当容器销毁之前,执行销毁方法,在销毁容器");
    }
}

编写Main方法

public class Main {
    public static void main(String[] args) {
        ApplicationContext ctx =  new ClassPathXmlApplicationContext("applicationContext.xml");

        // 销毁容器
        ((ClassPathXmlApplicationContext)ctx).close();
}

最后执行结果

4.5 依赖注入注解(@Inject、@Named)

@Inject用于依赖注入,相当于上面的3.1.1构造方法注入bean

@Inject 用于通过构造方法和set方法注入bean

@Named 当接口有多个实现类时,通过@Named可以指定注入的Bean(实现类)

 创建controller,service包,在controller包下创建UserController类,在service包下创建userService接口,在到service包下创建子包impl,最后在impl包创建UserServiceImpl类并实现userService接口

UserService接口

public interface UserService {
    // 添加用户
    void add();
}

UserServiceImpl类

@Service
public class UserServiceImpl implments UserService{
    public void add() {
        System.out.println("添加用户");
    }
}

 UserController类

该类需要注入UserService的实现类(bean),并调用add方法

@Controller
public class UserController {

    // UserService接口
    private UserService userService;

    /**
     * 构造方法注入
     * 注意:从spring4.3版本开始,如果构造方法注入时,
     * 注入的依赖只有一个实现类时,spring默认就会将这个实现类注入进来
     * 但注解需要写在属性上
     * @param userService
     */
    @Inject
    public UserController(UserService userService) {
        this.userService = userService;
    }

    // 添加用户
    public void add() {
        // 调用注入bean的add方法
        userService.add();
    }

}

 不编写构造方法时,并且只有一个实现类时,@Inject注解应该放在属性上

从spring4.3版本开始,如果构造方法注入时,
               只有一个实现类时,spring默认就会将这个实现类注入进来

@Controller
public class UserController {

    @Inject
    private UserService userService;

    // 添加用户
    public void add() {
        // 调用注入bean的add方法
        userService.add();
    }

}

编写Main方法

public class Main {

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserController controller = (UserController) context.getBean("userController");
        controller.add();
    }
}

最后执行结果

当UserService接口有多个实现类时,使用@Named注解来指定注入的实现类

在impl包下在添加UserService接口的实现类StudentServiceImpl

/*
 * @Service注解值表示在容器中bean标签的id属性,唯一标识
 */
@Service("studentService")
public class StudentServiceImpl implments UserService {

    public void add() {
        System.out.println("添加学生信息");
    }
}

UserController类使用@Named注解来指定注入的实现类

@Controller
public class UserController {

    private UserService userService;


    /**
     * 通过set方法来注入
     * 使用@Inject注解进行注入
     * 当有多个实现类时,可以结合@Named注解来指定想要注入的Bean的id
     * @param userService
     */
    @Inject
    @Named("studentService")
    public void setUserService(UserService userService) {
        this.userService = userService;
    }


    public void add() {
        userService.add();
    }
}

现在UserService接口有了两个实现类(UserServiceImpl,StudentServiceImpl)了,userController类通过@Named注解指定了注入的实现类为StudentServiceImpl,所以最终执行的结果为添加学生信息

4.6@Resource注解

@Resourcce注解同样是依赖注入,他是使用JSR250(java规提案)

提供的@Resource注解实现依赖注入。


* 它有一个name属性,在注入时指定需要注入的bean的id。这个注解

* 可以标注在类的字段上,也可以标注在set方法上实现注入功能,

* 但不支持标注在构造方法上,这是它的局限性。

 UserService接口

public interface UserService {
    // 添加用户
    void add();
}

UserServiceImpl类

@Service
public class UserServiceImpl implments UserService{
    public void add() {
        System.out.println("添加用户信息");
    }
}

 UserController类

将@Resource注解标注在类的字段上

@Controller
public class UserController {
    // 标注在类的字段上面
    @Resource
    private UserService userService;

    // 调用userService的add方法
    public void add() {
        userService.add();
    }
}

编写Main方法

    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserController controller = context.getBean(UserController.class);
        controller.addUser();
    }

最后执行结果

将@Ressource注解标注在set方法上

UserController类

@Controller
public class UserController {
    // 需要注入的bean,生成对应的set方法
    private UserService userService;

    /**
     * 将Resource注解标注在set方法上,默认会去掉set将set后面第一个字母改小写
     * 已userService命名
     */
    @Resource
    public void setUserService(UserServive usreService) {
        this.userService = userService;
    }  
    

    public void add() {
        userService.add();
    }
}

执行结果与上面同等

4.7 @Autowired注解、@Qualifier

@Autowired注解于@Resource注解作用一致


@Autowired由spring提供的注入注解


@Autowired注解可以标注在属性、构造方法、set方法上,而@Resource注解不支持标注在构造方法上


@Qualifier注解用于当依赖对象有多个实现类时,指定具体的一个实现类,等价于上面4.5中的@Named注解


如果不想使用@Qualifier注解时可以在实现类上使用@Primary注解来指定注入的优先级

创建UserService接口,并创建UserServiceImpl类,并实现UserService接口,在创建UserController类

UserService接口

public interface UserService {
    pubic void add();
}

UserServiceImpl类

@Service
public class UserServiceImpl implments UserService {
    @Override
    public void add() {
        System.out.println("添加用户信息!");
    }
}

UserController类

将@Autowired注解标注在构造上

@Controller
public class UserController {
 
    private UserService userService;

    /*
     * 将@Autorired标注在构造方法上
     */
    @Autowired
    public UserController(UserService userService){
        this.userService = userService;
    }

    public void add() {
        userService.add();
    }
}

 将@Autowired标注在属性上,无需编写构造方法

@Controller
public Class UserController{
    
    /*
     * 将注解标注在属性上,注解自动生成构造方法注入bean
     */
    @Autowired
    private UserService userService;

    public void add() {
        userService.add();
    }
    
}

将@Autowired注解标注在set方法上

@Controller
public Class UserController {
    private UserService userService;

    /**
     * 标注在set方法,name为将set去掉后面第一个字母改成小写(userService)
     */
    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public void add() {
        usereService.add();
    }

    
}

编写Main方法 

public Class Main{
    public static void main(String[] args) {
        ApplicationContext contex = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserController userController = (UserController) context.getBean("userController");
        userController.add();
    }
}

最后执行结果

 

 使用@Qualifier注解,当UserService接口在增加一个实现类时,这个时候就需要指定注入哪个实现类了

创建StudentServiceImpl类,并实现了UserService接口

@Service
public class StudentServiceImpl implments UserService {
    @Override
    public void add() {
        System.out.println("添加学生信息");
    }
}

修改UserController类,使用@Qualifier注解指定注入的实现类


在构造方法上使用

@Controller
public class UserController {

    private UserService userService;

    /**
     * 在构造方法中的参数指定注入的实现类为studentService
     * @Qualifier注解不能标注在构造方法上,只能标注在参数中
     */
    @Autowired
    public UserController(@Qualifier("studentService") UserService userService) {
        this.userService = userService;
    }
}

在set方法中使用

@Controller
public class UserController {

    private UserService userService;

    /**
     * 在set方法的参数指定注入的实现类为studentService
     */
    @Autowired
    public setUserController(@Qualifier("studentService") UserService userService) {
        this.userService = userService;
    }

    /*@Qualifier可以在set方法上标注,也可以在方法参数标注,二选一*/
    /*@Autowired
    @Qualifier("studentService")
    public setUserController(UserService userService) {
        this.userService = userService;
    }*/
}

最后执行结果:

如果不想使用@Qualifier注解指定注入的实现类,可以使用@Primary注解设置Bean注入的优先级别

/**
 * @Primary注解可以设置Bean注入优先级别
 * 你要指定哪个实现类需要注入就在哪加
 */
@Service
@Primary
public class StudentServiceImpl implments UserService {
    @Override
    public void add() {
        System.out.println("添加学生信息");
    }
}

执行结果

4.8 @RequiredArgsConstructor 注解

@RequiredArgsConstructor注解也是依赖注入的一种,有lombok提供,使用时需要导入lombok依赖

导入lombox的依赖

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.32</version>
        </dependency>

修改UserController

/**
 * 使用lombok来生成一个带参的构造方法
 * 注意:赋值的字段必须是final
 */
@Controller
@RequiredArgsConstructor
public class userController {

    // 注入的对象必须使用final关键字修饰
    private final userService userService;

    public void add() {
        userService.add();
    }
}

最后执行结果:


                                                                待更新

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2165761.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring6梳理12——依赖注入之注入Map集合类型属性

以上笔记来源&#xff1a; 尚硅谷Spring零基础入门到进阶&#xff0c;一套搞定spring6全套视频教程&#xff08;源码级讲解&#xff09;https://www.bilibili.com/video/BV1kR4y1b7Qc 12 依赖注入之注入Map集合类型属性 12.1 创建Student类和Teacher类 Student类中创建了run…

灵当CRM multipleUpload.php 文件上传致RCE漏洞复现

0x01 产品描述&#xff1a; 灵当CRM是一款专为中小企业量身定制的智能客户关系管理工具&#xff0c;由上海灵当信息科技有限公司开发和运营。该系统广泛应用于多个行业&#xff0c;包括金融、教育、医疗、IT服务及房地产等领域&#xff0c;旨在满足企业对客户个性化管理的需求&…

集合ArrayList常用方法

源代码&#xff1a; 输出结果&#xff1a;

小米Civi2机型工程固件 资源预览 刷写说明 与nv损坏去除电阻图示

小米Civi2机型机型代码为:ziyi。次期开始讲在博文中陆续解析机型nv损坏修复的一些步骤与当前机型去除校验电阻相关的图示与说明。注意。米系列机型有串码校验。去除电阻需要一定的技术,请谨慎操作。 通过博文了解 1💝💝💝-----此机型工程固件的资源刷写注意事项 2�…

【计算机网络 - 基础问题】每日 3 题(二十四)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏&…

音乐服务器测试报告

项目背景 该音乐服务器系统使用的是前后端分离的方式来实现,将相关数据存储到数据库中, 且将其部署到云服务器上. 前端主要构成部分有: 登录页面, 列表页面, 喜欢页面, 添加歌曲4个页面组成. 通过结合后端实现了主要的功能: 登录, 播放音乐, 添加音乐, 收藏音乐, 删除音乐, 删…

uniapp实现在表单中展示多个选项,并且用户可以选择其中的一个或多个选项

前言 uni-data-checkbox是uni-app的一个组件,用于在表单中展示多个选项,并且用户可以选择其中的一个或多个选项。该组件可以通过设置不同的参数来控制选项的样式、布局和行为。 提示:以下是本篇文章正文内容,下面案例可供参考 uni-data-checkbox组件具有以下特点:: 1、跨…

Git 工作区、暂存区与修改全解析

工作区和暂存区是 Git 中一个非常重要的概念&#xff0c;弄明白了他们&#xff0c;就弄明白了 Git 的很多操作到底干了什么。 ‍ 工作区&#xff08;Working Directory&#xff09; 工作区&#xff0c;就是一个目录&#xff0c;比如我的 LearnGit ​文件夹就是一个工作区&am…

JavaScript --模版字符串用反引号

用反引号 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice-width, i…

SpringBoot集成阿里easyexcel(一)基础导入导出

easyexcel主要用于excel文件的读写&#xff0c;可使用model实体类来定义文件读写的模板&#xff0c;对开发人员来说实现简单Excel文件的读写很便捷。可参考官方文档 https://github.com/alibaba/easyexcel 一、引入依赖 <!-- 阿里开源EXCEL --><dependency><gr…

《深度学习》ResNet残差网络、BN批处理层 结构、原理详解

目录 一、关于ResNet 1、什么是ResNet 2、传统卷积神经网络存在的问题 1&#xff09;梯度消失和梯度爆炸问题 2&#xff09;训练困难 3&#xff09;特征表示能力受限 4&#xff09;模型复杂度和计算负担 3、如何解决 1&#xff09;解决梯度问题 BN层重要步骤&#xff1a; 2…

Gstreamer中,使用mp4或者flv作为视频源去推流RTP等视频流时,需要先解码在编码才能正常

前言&#xff1a; 在Gstreamer中&#xff0c;视频源可以有很多&#xff0c;在很多时候&#xff0c;我们为了测试&#xff0c;会使用MP4等文件作为视频源进行测试&#xff0c;但是发现无论是我自己测试&#xff0c;还是很多网上的命令&#xff0c;都需要先对mp4的h264数据解码以…

等保测评实战:构建企业网络安全的铜墙铁壁

在数字化转型的浪潮下&#xff0c;企业面临的网络安全威胁日益复杂多变。信息安全等级保护&#xff08;等保&#xff09;测评作为国家强制性标准&#xff0c;不仅检验着企业的网络安全防护能力&#xff0c;更是企业构建网络安全“铜墙铁壁”的实战指南。本文将从实战角度&#…

华为云徐峰:AI赋能应用现代化,加速软件生产力跃升

2024年9月19日&#xff0c;在华为全联接大会2024的“AI赋能应用现代化&#xff0c;加速软件生产力跃升”论坛上&#xff0c;华为云PaaS服务产品部部长徐峰发表了主题演讲&#xff0c;介绍了未来应用智能化演进趋势&#xff0c;分享了智能化应用的行业实践&#xff0c;并发布了华…

Elasticsearch 启动后在浏览器输入http://localhost:9200 访问失败

windows Elasticsearch 启动后在浏览器输入http://localhost:9200 访问失败 文章目录 前言本地下载安装了个elasticsearch&#xff0c;启动成功了&#xff0c;在本地访问http://localhost:9200 无法访问&#xff01;&#xff01;&#xff01;难受了一下。 一、windows Elastics…

从文本图片到多模态:3D 数字人打开企业全域商业增长新空间

摘要&#xff1a;数字化与AI浪潮推动各行业变革&#xff0c;内容形式也发生巨变&#xff0c;从文本到多媒体的多模态表达&#xff0c;标志着内容创造走向升维。AIGC 3D生成技术的突飞猛进&#xff0c;彻底打破了传统3D内容生产门槛高、周期长、成本高昂的问题。将3D数字人的打造…

两种调用智谱AI API的方式

一、 用智谱AI依赖包调用 from zhipuai import ZhipuAI zhipuai_api_keyXXXXXXXXXXXXXXXXXX # 请填写您自己的APIKeymessages[{"role": "system", "content": "你是一名经验丰富的人工智能工程师&#xff0c;请你解答用户的问题"},{…

前端文件下载全流程

一、首先是点击下载函数功能 源代码&#xff1a; java const dow async (record: any) > {console.log(record,record);let date: any {}date.pcno record.pcnodate.fileName record.fileNamedate.gmtCreated dayjs(record.gmtCreated).format(YYYY-MM)date.importSta…

Electron 更换窗口图标、exe执行文件图标

首先在项目根目录下准备好图标&#xff1a; 配置窗口图标&#xff1a; 配置打包后 exe执行文件 的图标&#xff1a; 效果展示&#xff1a;

gitlab默认克隆地址的修改

目录 1.找到opt/gitlab/embedded/service/gitlab-rails/config目录&#xff0c;打开gitlab.yml 2.修改地址和端口 3.重启gitlab 1.找到opt/gitlab/embedded/service/gitlab-rails/config目录&#xff0c;打开gitlab.yml cd /opt/gitlab/embedded/service/gitlab-rails/confi…