聊一聊spring的常用注解

一、@value

javaBean

public class Bird {
	//使用@Value进行赋值:1,基本字符  2,springEL表达式, 3,可以读取 我们的配置文件
	@Value("James")
	private String name;
	
	@Value("#{20-2}")
	private Integer age;
	
	@Value("${bird.color}")
	private String color;
	
	public Bird() {
		super();
	}
	
	public Bird(String name, Integer age, String color) {
		super();
		this.name = name;
		this.age = age;
		this.color = color;
	}
	
	//getter、setter 方法.......
}

config

@Configuration
//加载 properties 文件
@PropertySource("classpath:/test.properties")
public class Cap8MainConfig {

    @Bean
    public Bird bird(){
        return new Bird();
    }
}

properties

bird.color=red

test

public class Cap8Test {
	@Test
	public void test01(){
		AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap8MainConfig.class);

		Bird bird = (Bird) app.getBean("bird");

		System.out.println(bird);
		System.out.println("IOC容器创建完成........");
		
		ConfigurableEnvironment environment = app.getEnvironment();
		System.out.println("environment===="+environment.getProperty("bird.color"));
		app.close();
	}
}

输出

Bird [name=James, age=18, color=red]
IOC容器创建完成........
environment====red

注:@PropertySource(“classpath:/test.properties”) 会把properties 配置文件中的标量都扫进环境变量中,@Value("${bird.color}")去环境变量中取值

二、注解方式 声明 bean 与注入 bean

1.声明bean的注解

@Component 组件,没有明确的角色
@Service 在业务逻辑层使用(service层)
@Repository 在数据访问层使用(dao层)
@Controller 在展现层使用,控制器的声明(C)

注:以上注解纳入 springBean中,默认bean的Id是类名首字母小写,可选参数 value 可指定自定义 bean Id,如下:
如果是①,那么这个 service 的 bean Id 就是 TtetService
如果是②,那么 service 的 bean Id就是myTestService

//@Service(value = "myTestService") //②
@Service   //①
public class TestService{
    
}

2、注入bean的注解

@Autowired:由Spring提供
@Inject:由JSR-330提供
@Resource:由JSR-250提供
都可以注解在set方法和属性上,推荐注解在属性上(一目了然,少写代码)。

@Autowired

1.@Autowired 是 spring 注解
2.@Autowired注解是按照类型(byType)装配依赖对象.
3.默认情况下它要求依赖对象必须存在,如果允许null值,可以设置它的required属性为false。
4.如果我们想使用按照名称(byName)来装配,可以结合@Qualifier注解一起使用。
5.可以设置属性@Autowired(required = false),表示如果没有接口的实现类,那么就注入 null
接口:

public interface ITestService {
    void judgeService();
}

service 实现类1 TestService

@Service
public class TestService implements ITestService{
	private TestDao testDao;

	@Override
	public void judgeService() {
		System.out.println("this is service");
	}
}

service 实现类2 TestService2

@Service
public class TestService2 implements ITestService{
	@Override
	public void judgeService() {
		System.out.println("this is service2");
	}
}

controller1

@Controller
public class TestController {
	@Qualifier("testService2")
	@Autowired(required = true)
	private TestService testService;

	public void testSwichService(){
		testService.judgeService();
	}

}

controller2

@Controller
public class TestController {
	@Autowired(required = true)
	private ITestService iTestService;

	public void testSwichService(){
		iTestService.judgeService();
	}

}

controller3

@Controller
public class TestController {
	@Qualifier("testService2")
	@Autowired(required = false)
	private ITestService iTestService;

	public void testSwichService(){
		iTestService.judgeService();
	}

}

test

public class Cap9Test {
	@Test
	public void test01(){
		AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap9MainConfig.class);

		TestController testController = app.getBean(TestController.class);
		testController.testSwichService();


	}
}

说明:
1.如果执行的是 controller1,因为注入的 service 类型定是具体的实现类 TestService,所以@Autowired通过 byType 可以确定的 service 是TestService,所以输出的是『this is service2』

2.如果执行的是 contoller2,因为注入的是一个接口ITestService:
           如果没有TestService2,ITestService的实现类就只有TestService,所以会正常的输出『this is service』
           现在ITestService有两个实现类 TestService、TestService2,所以@Autowired就会不知道该注入哪个实现类,最后会报错:发现了两个实现类

3.如果执行的是 controller3,同样注入的是一个接口ITestService,因为有注解@Qualifier(“testService2”),代表指定ITestService接口实现类的 bean Id,且必须是实现了接口ITestService的 service,因为此时@Autowired(required = false),所以找不到的话iTestService会为 Null,不会报错

@Resource

1.jdk 自带注解,由JSR-250提供
2.默认按照 name(实际是 beanId)进行装配,如果name匹配不到才按 type进行匹配。需要注意的是,如果只按 name 匹配,如果 name 匹配不到,就不会按照类型就行匹配了,会报找不到。
3.必须有一个合适的实现类注入进来,不然会报错

接口

public interface ITestService {
    void judgeService();
}

service 实现类1 TestService

@Service
public class TestService implements ITestService{
	@Override
	public void judgeService() {
		System.out.println("this is service");
	}
}

service 实现类2 TestService2

@Service
public class TestService2 implements ITestService{
	@Override
	public void judgeService() {
		System.out.println("this is service2");
	}
}

controller

@Controller
public class TestController {
    //所扫描的 bean 必须为ITestService的实现类

    //查找 beanId 为 『testService』的 bean
	@Resource(name = "testService")
	
	//查找类型为『TestService.class』的 bean
	@Resource(type = TestService.class)
	
	//查找 beanId 为 『testService』且类型为『TestService.class』的 bean
	@Resource(name = "testService",type = TestService.class)
	private ITestService iTestService;

	public void testSwichService(){
		iTestService.judgeService();
	}

}

注:Resource 也可以使用 @Qualifier,但是 Resource 本身可以设置 name 属性,再使用@Qualifier多余,所以一般没人这样用的

@Qualifier、@Primary

@Qualifier(“xxxx”):帮助注解 byName
@Primary:用在声明注解,在注入接口,且接口有多个实现类,在无法唯一判断注入哪个具体的实现类时,注入标记了@Primary的实现类(只能有一个实现类加入这种标记)

接口

public interface ITestService {
    void judgeService();
}

service 实现类1 TestService

@Primary
@Service
public class TestService implements ITestService{
	private TestDao testDao;

	@Override
	public void judgeService() {
		System.out.println("this is service");
	}
}

service 实现类2 TestService2

@Service
public class TestService2 implements ITestService{
	@Override
	public void judgeService() {
		System.out.println("this is service2");
	}
}

controller1

@Controller
public class TestController {
	@Autowired
	private ITestService iTestService;

	public void testSwichService(){
		iTestService.judgeService();
	}

}

controller2

@Controller
public class TestController {
	@Qualifier("testService2")
	@Autowired
	private ITestService iTestService;

	public void testSwichService(){
		iTestService.judgeService();
	}

}

test

public class Cap9Test {
	@Test
	public void test01(){
		AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(Cap9MainConfig.class);

		TestController testController = app.getBean(TestController.class);
		testController.testSwichService();


	}
}

如果执行 controller1, controller未指明具体注入哪个实现类,所以 注入标记了@Primary 的 service,最后输出『this is service』
如果执行controller2,controller 使用@Qualifier(“testService2”),指明了注入的 beanId ,所以最终输出为『this is service2』

@Autowired和@Resource 的区别

相同点
1.两个都是注入 bean 的注解
2.都支持@Qualifier、@Primary 注解(看过教程说 @Resource不支持@Primary,但是经过实验,是支持的)

不同点:
1.Autowired是 spring 的注解,Resource 是 jdk 的注解
2.Autowired有 require=false,如果找不到实现类就注入空。Resource 没有这种属性,找不到就报错
3.Autowired 只能默认通过 byType注入。Resource 可以通过 name、type 属性 来指定 byType、byName 注入。


特别的:在注入 bean 时,不管是 @Autowired、@Resource或是@Inject,都可以不靠@Qualifier、@Primary,或是@Resource的 name、type 属性来辅助注入唯一的实现类。只需要通过注入时的变量与 注册到 spring 容器中的 Bean Id 来对应即可,实际是利用 ByName 的属性:

接口:

public interface ITestService {
    void judgeService();
}

service 实现类1 TestService

@Service
public class TestService implements ITestService{

	@Override
	public void judgeService() {
		System.out.println("this is service");
	}
}

service 实现类2 TestService2

@Service
public class TestService2 implements ITestService{
	@Override
	public void judgeService() {
		System.out.println("this is service2");
	}
}

controller

@Controller
public class TestController {
	@Autowired
//	@Resource
//  @Inject

    //此处的变量名,需要与想要注入的实现类的 beanId 相同
	private ITestService TestService2;

	public void testSwichService(){
		TestService2.judgeService();
	}

}

最后输出结果:『this is service2』

未完,持续更新中。。。。。。

发布了14 篇原创文章 · 获赞 8 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/langwuzhe/article/details/105032980
今日推荐