ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring框架中@Autowired和@Resource的区别

2020-06-03 22:07:27  阅读:324  来源: 互联网

标签:UserServiceImpl Resource Service Autowired Spring bean UserService public


目录


Spring框架中@Autowired和@Resource的区别


在下载spring源码的漫长过程中....整理一下@Autowired 和 @Resource两个注解的区别和理解


1、注入原理

注入就是为某个对象的外部资源赋值(利用反射机制为类的属性赋值的操作),注入某个对象所需要的外部资源(包括对象、资源、常量数据等)

  • @Autowired是Spring的注解,Autowired默认先按 byType,如果发现找到多个 bean,则,又按照 byName方式比对,如果还有多个,则报出异常;

  • @Resource 是JDK1.6支持的注解默认按照名称( ByName)进行装配, 如果没有指定 name属性,当注解写在字段上时,默认取字段名,按照名称查找,如果注解写在 setter方法上默认取属性名进行装配。当找不到与名称匹配的 bean时才按照类型进行装配。

但是需要注意的是,如果 name属性一旦指定,就只会按照名称进行装配。

2、简单实例

UserService 接口

@Service
public interface UserService {
	public User findByUsername(String username);
}

UserServiceImpl 实现类

@Service
public class UserServiceImpl implements UserService{

	@Override
	public User findByUsername(String username) {
		return username;
	}
}

Controller中具体调用

@Controller
public class UserCenterController {
	@Autowired 
    UserService userService;
    
    userService.findByUsername("pianpianpianpian");

}
	

3、获取实例的具体过程

在Controller类中获取实例 userService时,若使用的是@Autowired,则程序在spring容器中查找相应的类型(UserService类型)的bean,这里刚好有且只有一个对应的bean(UserServiceImpl),则就把UserServiceImpl 自动装配到Controller类的实例(userService)中去了。值得一提的是这里的userService其实就是**UserServiceImpl **这个实现类。

同理,使用@Resource时候

先在容器中查找名为 userService的bean,在这个实例中是肯定找不到的,因为容器中的bean的名字应该是UserServiceImpl 实例中的@Service没有指定bean的value属性,所以注入的bean的名字就是类名,反之如果指定了就是指定的名字)。前面说到按照名字查找没有找到,然后再通过类型查找userService类型的bean,可以找到唯一的一个userService类型的bean(即实现类**UserServiceImpl **)


ps: 小结,个人理解的是 这里的接口是不会被注入bean的,只是用来接收数据和做规范的

通过查阅资料,发现这两个注解的效率是差不多的,不过@Resource可以应对一个接口对应多个实现类的情况,而@Autowired需要结合注解@Qualifier来使用。所以综合来说@Resource更好一点。

4、拓展

Q1、如果遇到一个接口对应多个实现类的情况:

如: UserServiceImpl 和 UserServiceImplSec两个相同类型的类

@Service
public class UserServiceImpl implements UserService{

	@Override
	public User findByUsername(String username) {
		return username;
	}
}
@Service
public class UserServiceImplSec implements UserService{

	@Override
	public User findByUsername(String username) {
		return username;
	}
}

可以通过以下两种方法确定具体要实例化的类:

1、使用 @Autowired + @Qualifier 或者 @Resource

	@Autowired
    @Qualifier("UserServiceImpl")
    private UserServiceImpl userServiceImpl;
---------------------------------------------------
    @Resource(name = "UserServiceImpl")
    private UserServiceImpl userServiceImpl;  

2、在实现类上添加 @Primary 注解来指定默认加载类

@Service
@Primary
public class UserServiceImpl implements UserService{

	@Override
	public User findByUsername(String username) {
		return username;
	}
}

Q2、Controller中明明可以直接实例化实现类UserServiceImpl的bean,为什么却用了接口UserService?

  • 这里确实也可以跳过接口直接实例化实现类UserServiceImpl的bean

如:

	@Autowired 
    UserServiceImpl userServiceImpl;
  • 使用接口是因为:
    • AOP编程思想,屏蔽了方法内部逻辑;
    • (通过使用多态)解耦;
    • 接口却可以多实现,方便后面的二次开发或维护
  • 当业务逻辑简单,变更较少,项目自用时,省略掉接口直接使用实现类更简单明了;反之则推荐使用接口;

Q3、关于注解和xml配置的区别 以及 @Service的具体作用

放一个大佬的传送: 点击前往

重点做一下@Service的的笔记:

在实体类上没有使用@Service的话,spring对应的xml中需要如下配置:

 <?xml version="1.0" encoding="UTF-8"?>
 <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
      xmlns="http://www.springframework.org/schema/beans"  
      xmlns:context="http://www.springframework.org/schema/context"  
      xsi:schemaLocation="http://www.springframework.org/schema/beans 
          http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
          http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context-4.2.xsd">
      
     <context:component-scan base-package="com.xrq" />
     
     <bean id="zoo" class="com.xrq.bean.Zoo" />
     <bean id="tiger" class="com.xrq.domain.Tiger" />
     <bean id="monkey" class="com.xrq.domain.Monkey" />
 </beans>

因为spring的配置文件里面还有12行~14行三个bean,下一步的简化是把这三个bean也给去掉,使得spring配置文件里面只有一个自动扫描的标签,增强Java代码的内聚性并进一步减少配置文件。

使用@Service 后:

java实体类:

@Service
public class Zoo
{
    @Autowired
    private Tiger ztiger;
    
    @Autowired
    private Monkey zmonkey;

}

@Service
public class Tiger
{
    private String tigerName;
}

@Service
public class Monkey
{
    private String monkeyName;
}

xml中:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
    xmlns="http://www.springframework.org/schema/beans"  
    xmlns:context="http://www.springframework.org/schema/context"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.2.xsd">
    
    <context:component-scan base-package="com.xrq" />
    
</beans>

最后感谢一下今天学习的原博主:点击前往

在放一篇自己感兴趣的文章:传送

标签:UserServiceImpl,Resource,Service,Autowired,Spring,bean,UserService,public
来源: https://www.cnblogs.com/ppppian2020/p/13040312.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有