Spring注入的方式

简介: 注入方式可以分为xml 方式、注解方式
勿将今日事留到明日

方式几种

整体可以分为:xml 方式、注解方式

  • xml

    • 手动: 构造方法(constructor-arg)、set方法(property)
    • 自动:byName、byType、constructor

xml方式

手动

我们先来看下每种方式是怎么使用的!

构造方法

提供两个类,一个是 OrderService,另外一个是 UserServiceUserService 中包含OrderService 属性,一个test方法,一个有参构造方法和一个无参构造方法

public class OrderService {
}

public class UserService {

    OrderService orderService;

    public UserService(){
        System.out.println("xml 无参构造注入" + orderService);
    }
    public UserService(OrderService orderService1){
        System.out.println("xml 有参构造注入" + orderService1);
        orderService = orderService1;
    }
    
    public void test(){
        System.out.println(orderService);
    }
}

我们可以看一下 xml 中的配置方式, constructor-arg 标签

<bean class="com.gongj.populateBean.OrderService" id="orderService"></bean>

<bean class="com.gongj.populateBean.UserService" id="userService">
   <constructor-arg index="0" ref="orderService"></constructor-arg>
</bean>
验证
public static void main(String[] args) {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config2.xml");
        UserService bean = context.getBean(UserService.class);
        bean.test();
}
结果:
xml 有参构造注入com.gongj.populateBean.OrderService@14514713
com.gongj.populateBean.OrderService@14514713

set方式

新增一个setOrder方法。这个setOrder方法用来注入 OrderService 的。


    public void setOrder(OrderService order){
        System.out.println("xml property方法注入" + order);
        orderService = order;
    }

修改 xml 中的配置方式,注意看 UserService的配置,将 constructor-arg 标签修改为了 property 标签,name 配置的值是 UserService 类中 setOrder的名称(省略set并首字母小写) ,ref 配置的值是上方OrderServiceid属性值,也就是 beanName

    <bean class="com.gongj.populateBean.OrderService" id="orderService">
    </bean>

    <bean class="com.gongj.populateBean.UserService" id="userService">
        <property name="order" ref="orderService"></property>
    </bean>
set方式验证
xml 无参构造注入null
xml property方法注入com.gongj.populateBean.OrderService@255316f2
com.gongj.populateBean.OrderService@255316f2

没有指定构造方法,默认走无参构造。

自动

先提一下 bean 标签里有个属性 autowire,这个属性的值有五种情况:nobyNamebyTypeconstructorautodetect

  • no:默认值,也就是不使用自动注入,也就是上面那种两种手动方式,在 xml 中配置 property标签或者 constructor-arg标签
  • byName:根据实体类中的set方法名称进行自动注入,不需要再配置 property标签
  • byType:根据实体类中的set方法的参数类型进行自动注入。
  • constructor:根据构造函数进行匹配,不需要再配置 constructor-arg标签。
  • autodetect:如果有默认的构造方法,通过 construct的方式自动装配,否则使用 byType的方式自动装配,Spring3.0被弃用。

byName

  • 反例:
public void setOrder(OrderService order){
        orderService = order;
}

就根据 order 这个名称(省略set并首字母小写)作为 beanName 去寻找Bean。如果找到了对应的Bean,才会将 Bean 赋值给方法的参数,并执行set方法。否则不会发生任何改变。(PS:当然在本例中,根据 order 这个名称是找不到 bean的,因为在xml配置的 beanName 叫 orderService,所以需要增加 set 方法并方法名称为 setOrderService

  • 正例
public void setOrderService(OrderService order){
        System.out.println("byName 方法注入" + order);
        orderService = order;
}
结果:
xml 无参构造注入null
byName 方法注入com.gongj.populateBean.OrderService@255316f2
com.gongj.populateBean.OrderService@25531

byType

根据 OrderService这个类型去寻找。如果找到多个相同类型则抛出异常。只需将byName修改为byType就会出现下面这种情况:

结果:
xml 无参构造注入null
xml property方法注入com.gongj.populateBean.OrderService@6e5e91e4
byName 方法注入com.gongj.populateBean.OrderService@6e5e91e4
com.gongj.populateBean.OrderService@6e5e91e4

这是由于 setOrder方法与setOrderService方法的参数类型都是 OrderService

constructor

在之前 UserService的基础上再增加一个有参构造方法。将byType修改为constructor

  • 示例
public UserService(OrderService orderService1,OrderService orderService2){
        System.out.println("两个参数有参构造注入" + orderService1 +"==="+ orderService2);
        orderService = orderService1;
}
结果:
两个参数有参构造注入com.gongj.populateBean.OrderService@46fbb2c1===com.gongj.populateBean.OrderService@46fbb2c1
com.gongj.populateBean.OrderService@46fbb2c1

如果有多个构造方法,会调用参数多的那个构造方法。

注解方式

随着 Spring 的发展,许许多多的注解可以替换xml的配置了,比如 @Bean替换了<bean>@Scope替换了 scope@Autowired 替换了 autowire 等等。我们这篇就使用一下 @Autowired的注入方式。

使用 @Autowired 注解了呢,就可以省略上面所写的 set 方法了。

public class UserService {
    @Autowired
    OrderService orderService;

    public void test(){
        System.out.println(orderService);
    }
}

可以看到UserService类里面就变得很简洁了。由于这里使用的是 ClassPathXmlApplicationContext这个容器,所以需要在 xml 中增加配置,如下:

<context:annotation-config/>

这个配置的作用是:激活已经在Spring容器里注册过的bean,我们已经通过 xml 的方式向 Spring 注册 Bean了。

当然你可能会觉得既然我都使用注解了,为什么还要在 xml 中注册 bean 呢?如果你有这种想法,你可以使用下面一种方式,在 xml 中增加配置,指定扫描包路径,如下:

<context:component-scan base-package="com.gongj.populateBean"/>

作用:具备 <context:annotation-config> 的所有功能,还可以扫描指定的 package 下面的类并注册为bean。

在类上加上注解Component,将该类注册到 Spring 容器中

@Component
public class UserService {}

如果你完全都不想有 xml 文件,那你可以使用如下方式:

        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppApplication.class);

切换容器,使用AnnotationConfigApplicationContext

新增 AppApplication类,类的内容如下:

@ComponentScan(basePackages = {"com.gongj.populateBean"})
public class AppApplication {
}

使用 ComponentScan注解指定扫描包路径。上述代码不再概述。

OK!我们回到正题 @Autowired 注解。使用了Autowired 注解之后,我们可以省略掉 set 方法,增加了我们的摸鱼时间 (* ̄︶ ̄)!

  • 如你对本文有疑问或本文有错误之处,欢迎评论留言指出。如觉得本文对你有所帮助,欢迎点赞和关注。
相关文章
|
Java Spring
Spring—Bean的装配方式—基于注解的七种装配方式
Spring—Bean的装配方式—基于注解的七种装配方式
534 0
|
资源调度 JavaScript Java
服务器支持访问静态文件的几种方式:Spring、Tomcat、Vue
服务器支持访问静态文件的几种方式:Spring、Tomcat、Vue
|
运维 Java 数据库连接
两种方式实现Spring 业务验证
验证在任何时候都非常关键。考虑将数据验证作为业务逻辑开发有利也有弊,Spring 认为,验证不应该只在Web 端进行处理,在服务端也要进行相应的处理,可以防止脏数据存入数据库中,从而避免为运维同学和测试同学造成更大的困扰,因为数据造成的bug会更加难以发现,而且开发人员关注点也不会放在数据本身的问题上,所以做服务端的验证也是非常有必要的。考虑到上面这些问题,Spring 提供了两种主要类型的验证:
425 0
|
Java Spring
spring创建Bean的9种方式,你用过几种?
spring创建Bean的9种方式,你用过几种?
799 0
|
Java 数据库连接 Spring
Spring整合Mybatis,SqlSessionDaoSupport方式
SqlSessionDaoSupport 是一个抽象的支持类,用来为你提供 SqlSession。调用 getSqlSession() 方法你会得到一个 SqlSessionTemplate🙌 接口实现类:(此类继承SqlSessionDaoSupport即可)
491 2
|
XML Java 数据库连接
Spring整合Mybatis,SqlSessionTemplate方式
MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。它将允许 MyBatis 参与到 Spring 的事务管理之中,创建映射器 mapper 和 SqlSession 并注入到 bean 中,以及将 Mybatis 的异常转换为 Spring 的 DataAccessException。 最终,可以做到应用代码不依赖于 MyBatis,Spring 或 MyBatis-Spring
893 2
|
XML Java 数据格式
​将Bean交给Spring容器管理有几种方式?
所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。
557 0
​将Bean交给Spring容器管理有几种方式?
|
Java Spring
Spring读取配置文件的几种方式
Spring读取配置文件的几种方式
240 1
扯一把 Spring 的三种注入方式,到底哪种注入方式最佳?
循环依赖这个问题,按理说我们在日常的程序设计中应该避免,其实这个本来也是能够避免的。不过由于种种原因,我们可能还是会遇到一些循环依赖的问题,特别是在面试的过程中,面试考察循环依赖,主要是想考察候选人对 Spring 源码的熟悉程度,因为要把循环依赖这个问题解释清楚,涉及到不少 Spring 源码。 今天松哥抽空和大家简单聊聊这个话题,问题比较庞大,我可能花几篇文章来和大家分享下,今天先来聊聊实例的注入方式。