欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > spring自动装配

spring自动装配

2024/11/30 10:53:58 来源:https://blog.csdn.net/2301_76862031/article/details/142093249  浏览:    关键词:spring自动装配

spring自动装配

        Spring 框架提供了一种机制,称为自动装配(Autowired),它允许 Spring 容器自动将依赖注入到 Bean 中,而无需显式地使用 XML 配置文件或构造函数注入。自动装配简化了依赖注入的过程,使得代码更加简洁和易于维护。

1 自动装配的基本概念

        自动装配是指 Spring 容器自动为一个 Bean 的属性找到合适的依赖对象,并将其注入。Spring 支持多种自动装配策略,包括:

  1. no: 默认情况下,Spring 不会自动装配任何 Bean。
  2. byName: Spring 尝试根据属性名自动装配 Bean。
  3. byType: Spring 尝试根据类型自动装配 Bean。
  4. constructor: 类似于 byType,但适用于构造函数参数。
  5. autodetect: 如果存在带有一个参数的构造函数,则使用 constructor;否则使用 byType。

2 基础环境准备

1.新建module

  1. 打开现有的Maven项目
  2. 添加新模块
    1. 在IntelliJ IDEA中,右键点击项目的根目录 -> New > Module... -> 选择Maven Module
    2. 在Eclipse中,右键点击项目的src/main/java目录 -> New > Other... -> 选择Maven类别下的Module
  3. 填写模块信息
    1. 组织ID (groupId):与主项目相同。
    2. 艺术品ID (artifactId):模块的名称。
    3. 版本 (version):与主项目相同。
    4. 包装 (packaging):根据模块的功能选择warjarpom
  4. 完成创建:点击完成按钮,IDE将创建新的模块。

2.导入相关的依赖

        在项目的pom.xml文件夹中导入一下依赖

 <dependencies>

        <!--导入spring-context依赖-->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>6.1.12</version>

        </dependency>
        <!--导入测试依赖-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <!--导入日志框架-->

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.23.1</version>
        </dependency>

        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-slf4j2-impl</artifactId>
            <version>2.23.1</version>
        </dependency>

     

</dependencies>

注:导入依赖后需要刷新Maven,否则依赖不会导入

如果没有出现上面这个图标,你则需要进行如下步骤

idea===>最右边的栏===》Maven===>点击打开===》新弹出来的界面中===》点击刷新按钮==》就会出现Maven刷新图标====》点击刷新就能刷新了

3.新建SpringConfig配置文件

配置文件中的内容如下

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

4.创建User类

        下面是一个user类,name,age,有参构造,无参数构造,get,set方法

package org.xiji;public class User {private String name;private int age;public User(String name, int age) {this.name = name;this.age = age;}
     public User() {}
    public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}

5.创建Teacher类

package org.xiji;public class Teacher {private User user;public Teacher(User user) {this.user = user;}public Teacher() {}/**** 点名*/ public void call() {System.out.println("老师点名"+user.getName()+"同学");}public User getUser() {return user;}public void setUser(User user) {this.user = user;}
}

3 在 XML 配置中启用自动装配

1.通过类型装配

        在SpringConfig.xml中编写配置文件

<!--通过类型-->
<bean id="userByType" class="org.xiji.User" autowire="byType"><property name="age" value="18"></property><property name="name" value="xiji"></property></bean>
<bean id="teacher" class="org.xiji.Teacher" autowire="byType"></bean>

测试

 

 

:可以看到,我们并没有配置和获取User相关的信息,但是调用teacher.call()点名方法时,却输出了我们在SpringConfig.xml文件中配置的user,但是我们也要注意,如果这个类有多个实例化对象时,会包错,错误原因是多个实例化对象,但不知道注入哪一个。

2.通过名称装配

        在SpringConfig.xml中编写配置文件

<!--通过名字-->
<bean id="teacher" class="org.xiji.Teacher" autowire="byName"></bean><bean id="user" class="org.xiji.User" autowire="byName"><property name="age" value="18"></property><property name="name" value="张三"></property>
</bean>

测试结果

可以看到依旧可以成功

注:如果User的bean id与Teacher方法中属性名不一致时,使用name注入出现错误        

        修改配置文件

<?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="teacher" class="org.xiji.Teacher" autowire="byName"></bean><bean id="userByName" class="org.xiji.User" autowire="byName"><property name="age" value="18"></property><property name="name" value="张三"></property></bean></beans>

错误收集

java.lang.NullPointerException: Cannot invoke "org.xiji.User.getName()" because "this.user" is null

    at org.xiji.Teacher.call(Teacher.java:19)
    at ByTypeTest.test(ByTypeTest.java:13)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
    at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)


 

解决办法:

        注入时,使用正确的名字,即可解决

4. 使用@Autowired注解中使用自动装配

1.配置componentScan包扫描

        下面方法任选其中一种

1)在SpringConfig.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.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">
<!--配置包扫描-->
<context:component-scan base-package="org.xiji"></context:component-scan>
</beans>

:把红色的替换为你自己的包路径,经过包扫描可以使用注解

2)配置类中配置

注:需要新建一个配置类,并且在类上加入@Configuration 和@ComponentScan("包名")

package org.xiji.config;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;@Configuration
@ComponentScan("org.xiji")
public class MyConfig {}

2.@Autowired的使用

这里用javaweb中的视图控制层Controller业务逻辑层Service层调用为例

1)基础准备
        controller
package org.xiji.controller;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.xiji.service.WebService;@Controller
public class WebController {@AutowiredWebService webService;/*** 调用service*/public void call(){webService.call();}
}

注: 

        @Autowired 自动装配注解

        @Controller 这个是标注controller注解

        @Resource 这个也是自动装配的注解

        service

service接口

package org.xiji.service;public interface WebService {public void call();
}

service接口实现类

package org.xiji.service.impl;import org.springframework.stereotype.Service;
import org.xiji.service.WebService;@Service
public class WebServiceImpl implements WebService {public void call(){System.out.println("你好啊,我的Spring");}
}

注:

        @Service是service层的注解

2)测试
        1.通过xml文件扫描配置文件测试
/*** 通过xml配置文件创建对象*/
@Test
public void test(){System.out.println("通过xml配置文件创建对象");ApplicationContext context  = new ClassPathXmlApplicationContext("SpringConfig.xml");WebController webController = context.getBean("webController", WebController.class);webController.call();
}

        2.通过config配置类测试
/*** 通过配置类创建对象*/@Test
public void test2(){System.out.println("通过配置类创建对象");ApplicationContext context  = new AnnotationConfigApplicationContext(MyConfig.class);WebController webController = context.getBean("webController", WebController.class);webController.call();
}

版权声明:

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

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