自动注入那些事

自动注入那些事

现在作为Java开发,spring已经是必备的技能,而spring实现原理就是依赖注入,早期依赖注入需要通过配置xml文件,很繁琐,总是因为少写或写错bean,而前功尽弃,重新打包上线,要特别小心。后来有了注解注入,才轻松了很多。今天来说一下自动注入的前世今生,包括xml注入,自动注入,以及注解注入@Resource、@Autowired和@AllArgsConstructor等。今天来说下注入的那些事。

注入的方式

先说下注入的方式有哪些

常用的注入方式有,Setter方法注入、构造器注入、自动装配、注解注入等。

1.Setter方法注入

Setter方法注入就是通过在类中实现Set方法来实现属性或者对象的注入,如下所示

假如要给UserService类,要注入UserDao对象。先在标签中声明一个UserDao的Bean,然后把它注入到userService的bean里,然后再在UserSerice类里,使用它。写法如下

UserDao类

public class UserDao{
    User getUserById(String userId);
}

UserService 类


public class UserSericeImpl{
    
    private UserDao userDao;
    
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    
    public User getUser(String userId){
        User user = userDao.getUserById(userId);
        ...
    }
}

xml配置

<bean id="userDao" class="com.murong.dao.UserDao"></bean>

<bean id="userService" class="com.murong.service.UserService">
    <property name="userDao" ref="userDao"></property>
</bean>
2.构造器注入

构造器注入就是通过类的构造器方法去注入

与Setter注入的主要区别就是在标签文件中,他把userService的bean里的Property替换成了constructor-arg,并且在类中的注入的Set方法改成了构造方法。

UserService 类

public class UserSericeImpl{
    
    private UserDao userDao;
    
    public UserSerice(UserDao userDao) {
        this.userDao = userDao;
    }
    
    public User getUser(String userId){
        User user = userDao.getUserById(userId);
        ...
    }
}

xml配置

<bean id="userDao" class="com.murong.dao.UserDao"></bean>

<bean id="userService" class="com.murong.service.UserService">
    <constructor-arg name="userDao" ref="userDao"></constructor-arg>
</bean>
3.自动装配

spring提供了自动装配的功能,简化了我们的配置,自动装配默认是不打开的,常用的方式有两种:

ByName: 通过参数名自动装配,如下所示,当userService的bean的autowire 被设置为ByName后,IOC容器会根据名字来自动装配,当发现userService类中有个userDao属性时,会看IOC容器中有没有Id为userDao的bean,有就装配进去。

<bean id="userDao" class="com.murong.UserDao"></bean>
<bean id="userService" class="com.murong.UserService" autowire="byName"/>

ByType:通过参数类型自动装配,当autowire被设置为byType后,IOC容器会看看里面有没有UserDao类型的,有就装配进去。

4.注解注入

随着时间的推移,使用xml的原始注入方式已经渐渐被注解注入替换,但底层原理还没有变,只是写法变了。

1.@Resource

先来说下@Resource ,Resurce注解是JDK1.6开始提供的一种注解方式,需要引入包(javax.annotation.Resource),它默认是通过名字(byName)来进行装配,当找不到与之匹配的名字时,才会按照类型(byType)进行匹配。如果都没有匹配上,或者找到了多个,就会报错。注入原理类似自动装配

实例如下

public class UserServiceImpl {
    @Resource
    private final UserDao userDao;
}
2.@Autowired

再来说下Autowired,Autowired 是Spring 提供的一种注解方式,需要引入包(org.springframework.beans.factory.annotation.Autowired),它默认是通过类型(byType)来进行注入.如果要使用byName注入,可以结合@Qualifier注解一起使用。

public class UserServiceImpl {
	@Autowired
	private final UserDao userDao;
}
public class UserServiceImpl {
    @Autowired
    @Qualifier("userDao")
    private final UserDao userDao;
}
3.@ AllArgsConstructor

最后说下AllArgsConstructor, AllArgConstactor是第三方lombok提供的一种注解方式,他需要引入lombok包,它是使用在类上的注解,它会生成一个构造函数,这个构造函数包含所有已经声明的字段属性。原理就是按照构造器注入。有了AllArgsConstructor,你就不用在每一个字段属性上添加注解了。真的一个顶N个。

需要引入lombok

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.16.10</version>
    <scope>provided</scope>
</dependency>

@AllArgsConstructor
public class UserServiceImpl {
    private final UserDao userDao;
    private final StudentDao studentDao;
    private final CourseDao courseDao;
}
public class UserServiceImpl {
    @Autowired
    private final UserDao userDao;
    @Autowired
    private final StudentDao studentDao;
    @Autowired
    private final CourseDao courseDao;
}

注入可能出现的问题

注入可能出现循环依赖问题,例如AService依赖BService,并且BService又依赖AService这种情况,如果涉及到两个类的互相依赖时,运行时会报错。解决办法就是,都在AService处理,或者都在BService里处理。

总结

落(lao)胎了一周大概,终于生出来了,望各位客官喜欢,可以拍砖吹水,但是如果感觉对你有那么一丢丢的帮助,别忘了一键三连哦!

上一篇:SSM自学笔记(一)


下一篇:关于mysql 的 autoCommit 参数