使用@Resource注解和@Inject注解
使用@Resource注解和@Inject注解
1.@Resource和@Inject概述
1.1.@Resource注解
@Resource注解是Java规范里面的,也可以说它是JSR250规范里面定义的一个注解。该注解默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,那么默认取字段名将其作为组件的名称在IOC容器中进行查找,如果注解写在setter方法上,那么默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的一点是,如果name属性一旦指定,那么就只会按照名称进行装配。
@Resource注解的源码,如下所示:
package javax.annotation;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface Resource {
String name() default "";
String lookup() default "";
Class<?> type() default java.lang.Object.class;
enum AuthenticationType {
CONTAINER,
APPLICATION
}
AuthenticationType authenticationType() default AuthenticationType.CONTAINER;
boolean shareable() default true;
String mappedName() default "";
String description() default "";
}
1.2.@Inject注解
@Inject注解也是Java规范里面的,也可以说它是JSR330规范里面定义的一个注解。该注解默认是根据参数名去寻找bean注入,支持Spring的@Primary注解优先注入,@Inject注解还可以增加@Named注解指定要注入的bean
@Inject注解的源码,如下所示:
package javax.inject;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import java.lang.annotation.Documented;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
@Target({ METHOD, CONSTRUCTOR, FIELD })
@Retention(RUNTIME)
@Documented
public @interface Inject {}
2.实战案例
2.1.测试@Resource注解
将项目中的BookService类标注在bookDao字段上的@Autowired注解和@Qualifier注解注释掉,然后添加上@Resource注解,如下所示:
package com.tianxia.springannotation.service.impl;
import com.tianxia.springannotation.dao.BookDao;
import com.tianxia.springannotation.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* BookServiceImpl
* @author liqb
* @date 2023-04-21 16:38
**/
@Service
public class BookServiceImpl implements BookService {
@Resource
private BookDao bookDao;
/**
* 打印方法
* @author liqb
* @date 2023-05-06 13:09
*/
public void print() {
System.out.println(bookDao);
}
@Override
public String toString() {
return "BookService [bookDao=" + bookDao + "]";
}
}
运行一下测试方法,输出的结果信息如下所示:
/**
* 测试方法
* @author liqb
* @date 2023-05-06 13:14
*/
@Test
public void test01() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);
BookService bookService = applicationContext.getBean(BookService.class);
System.out.println(bookService);
applicationContext.close();
}
使用@Resource注解也能够自动装配组件,只不过此时自动装配的是lable为1的bookDao,而不是我们在MainConfigOfAutowired配置类中配置的优先装配的lable为2的bookDao。MainConfigOfAutowired配置类中配置的lable为2的bookDao如下所示:
package com.tianxia.springannotation.config;
import com.tianxia.springannotation.dao.BookDao;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
/**
* 配置类
* @author liqb
* @date 2023-05-06 13:11
**/
@Configuration
@ComponentScan({"com.tianxia.springannotation.service", "com.tianxia.springannotation.dao", "com.tianxia.springannotation.controller"})
public class MainConfigOfAutowired {
/**
* 注入bookDao对象
* @author liqb
* @date 2023-05-06 13:27
* @return
*/
@Primary
@Bean("bookDao2")
public BookDao bookDao() {
BookDao bookDao = new BookDao();
bookDao.setLable("2");
return bookDao;
}
}
进一步说明,@Resource注解和@Autowired注解的功能是一样的,都能实现自动装配,只不过@Resource注解默认是按照组件名称(即属性的名称)进行装配的。虽然@Resource注解具备自动装配这一功能,但是它是不支持@Primary注解优先注入的功能的,而且也不能像@Autowired注解一样能添加required=false属性。
@Resource注解时,可以通过@Resource注解的name属性显示指定要装配的组件的名称。例如,想装配lable为2的bookDao,只需要为@Resource注解添加 name="bookDao2"属性即可,如下所示:
package com.tianxia.springannotation.service.impl;
import com.tianxia.springannotation.dao.BookDao;
import com.tianxia.springannotation.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
/**
* BookServiceImpl
* @author liqb
* @date 2023-04-21 16:38
**/
@Service
public class BookServiceImpl implements BookService {
@Resource(name="bookDao2")
private BookDao bookDao;
/**
* 打印方法
* @author liqb
* @date 2023-05-06 13:09
*/
public void print() {
System.out.println(bookDao);
}
@Override
public String toString() {
return "BookService [bookDao=" + bookDao + "]";
}
}
2.2.测试@Inject注解
在BookService类中,将@Resource注解注释掉,添加@Inject注解,如下所示:
package com.tianxia.springannotation.service.impl;
import com.tianxia.springannotation.dao.BookDao;
import com.tianxia.springannotation.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.inject.Inject;
/**
* BookServiceImpl
* @author liqb
* @date 2023-04-21 16:38
**/
@Service
public class BookServiceImpl implements BookService {
@Inject
private BookDao bookDao;
/**
* 打印方法
* @author liqb
* @date 2023-05-06 13:09
*/
public void print() {
System.out.println(bookDao);
}
@Override
public String toString() {
return "BookService [bookDao=" + bookDao + "]";
}
}
运行测试方法,输出的结果信息如下所示:
/**
* 测试方法
* @author liqb
* @date 2023-05-06 13:14
*/
@Test
public void test01() {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);
BookService bookService = applicationContext.getBean(BookService.class);
System.out.println(bookService);
applicationContext.close();
}
使用@Inject注解默认输出的是lable为2的bookDao。这是因为@Inject注解和@Autowired注解一样,默认优先装配使用了@Primary注解标注的组件。
其实,这也进一步说明了,@Inject注解和@Autowired注解的功能是一样的,都能实现自动装配,而且它俩都支持@Primary注解优先注入的功能。只不过,@Inject注解不能像@Autowired注解一样能添加required=false属性,因为它里面没啥属性。
3.@Resource和@Inject这俩注解与@Autowired注解的区别
3.1.不同点:
- @Autowired是Spring中的专有注解,而@Resource是Java中JSR250规范里面定义的一个注解,@Inject是Java中JSR330规范里面定义的一个注解
- @Autowired支持参数required=false,而@Resource和@Inject都不支持
- @Autowired和@Inject支持@Primary注解优先注入,而@Resource不支持
- @Autowired通过@Qualifier指定注入特定bean,@Resource可以通过参数name指定注入bean,而@Inject需要通过@Named注解指定注入bean
3.2.相同点
三种注解都可以实现bean的自动装配。
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)