最近在看spring注解的网上视频教程,为了以后回头看看,我将内容写了下来,如下:
我们在idea中创建一个maven的quickstart工程。
我们在pom.xml依赖中添加需要添加的依赖。
org.springframework
spring-context
5.1.2.RELEASE
我们在目录下创建dao包,在此包下面创建一个MyDao的类文件,此文件的类名上面添加了注解@Repository
。
MyDao:
package com.xiaojian.dao;
import org.springframework.stereotype.Repository;
@Repository
public class MyDao {
}
我们在目录下创建service包,在此包下面创建MyService的类文件,此文件的类名上面添加了注解@Service
。
MyService:
package com.xiaojian.service;
import com.xiaojian.dao.MyDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MyService {
@Autowired
private MyDao myDao;
@Override
public String toString() {
return "MyService{" +
"myDao=" + myDao +
'}';
}
}
我们在目录下创建controller包,在此包下面创建一个MyController的类文件,此文件的类名上面添加了注解@Controller
。
MyController:
package com.xiaojian.controller;
import com.xiaojian.service.MyService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
@Controller
public class MyController {
@Autowired
private MyService myService;
@Override
public String toString() {
return "MyController{" +
"myService=" + myService +
'}';
}
}
Spring利用依赖注入(DI),完成对IOC容器中各个组件的依赖关系的赋值。
@Autowired
自动注入(spring注解)@Autowired
注入实例我们在目录下创建config包,在此包下面创建MainConfigOfAutowired类文件,此类作为配置类。
MainConfigOfAutowired:
package com.xiaojian.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration //此类作为配置类
//扫描service、dao、controller三个包下面的配置类。
@ComponentScan({"com.xiaojian.service","com.xiaojian.dao","com.xiaojian.controller"})
public class MainConfigOfAutowired {
}
我们在目录下创建test包,在此包下面创建Test_MainConfigOfAutowired类文件。
Test_MainConfigOfAutowired:
package com.xiaojian.test;
import com.xiaojian.config.MainConfigOfAutowired;
import com.xiaojian.dao.MyDao;
import com.xiaojian.service.MyService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test_MainConfigOfAutowired {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);
//看看myservice这个对象里面注入的mydao的信息
MyService myService = applicationContext.getBean(MyService.class);
System.out.println(myService);
//看看mydao这个对象的信息
MyDao myDao = applicationContext.getBean(MyDao.class);
System.out.println(myDao);
applicationContext.close();
}
}
运行Test_MainConfigOfAutowired测试类,测试结果:
D:\basic\jdk\jdk1.8.0_131\bin\java ...
MyService{myDao=com.xiaojian.dao.MyDao@3d3fcdb0}
com.xiaojian.dao.MyDao@3d3fcdb0
Process finished with exit code 0
如上,在MyService这个对象中,它内部的mydao是3d3fcdb0,而我们IOC容器中本身的MyDao这个对象为3d3fcdb0,所以我们在MyService中通过@Autowired
注解注入的MyDao是成功的。
@Autowired
与@Bean
对比MyDao:
package com.xiaojian.dao;
import org.springframework.stereotype.Repository;
//名字默认是类名的小写首字母的方式
@Repository
public class MyDao {
//此处默认为1
private String label = "1";
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
@Override
public String toString() {
return "MyDao{" +
"label='" + label + '\'' +
'}';
}
}
MainConfigOfAutowired:
package com.xiaojian.config;
import com.xiaojian.dao.MyDao;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan({"com.xiaojian.service","com.xiaojian.dao","com.xiaojian.controller"})
public class MainConfigOfAutowired {
//此处是我们在配置类中添加的一个Bean,此处我们命名为myDao2,与MyService中@Autowired注入的mydao1区分开来。
@Bean("myDao2")
public MyDao myDao(){
MyDao myDao=new MyDao();
myDao.setLabel("2");
return myDao;
}
}
我们在此类中添加一个bean的注册,目的在于看看我们在MyService类文件中通过@Autowired
注解注入的MyDao是系统配置类的还是bean注册的。
我们修改Test_MainConfigOfAutowired测试类。
Test_MainConfigOfAutowired:
package com.xiaojian.test;
import com.xiaojian.config.MainConfigOfAutowired;
import com.xiaojian.dao.MyDao;
import com.xiaojian.service.MyService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test_MainConfigOfAutowired {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(MainConfigOfAutowired.class);
//看看myservice这个对象里面注入的mydao的信息
MyService myService = applicationContext.getBean(MyService.class);
System.out.println(myService);
applicationContext.close();
}
}
运行Test_MainConfigOfAutowired配置类。
测试结果:
D:\basic\jdk\jdk1.8.0_131\bin\java ...
MyService{myDao=MyDao{label='1'}}
Process finished with exit code 0
如上,控制台打印出了MyService中的通过@Autowired
注解注入的MyDao是来自MyDao这个配置类来的,而不是来自@Bean
注解注入进来的。
@Autowired
注解注入的内容,是系统通过配置类注入进IOC的对象,而不是通过@Bean
注入的内容。如果将MyService中的MyDao属性改成mydao2,那么系统通过
@Autowired
注解注入的mydao2就是通过@Bean
注入进IOC中的内容。@Autowired private MyDao myDao2;
如果存在没赋值好的时候,我们可以将
@Autowired
注解的required属性设置为false来解决这个问题。设置这个属性后,如果没有赋值好,此处也没有问题,就是不会将此注解标注的mydao装配到类中。@Autowired(required = false)
@Qualifier
注解指定装配我们除了用上面方法装配组件,我们可以通过@Qualifier
指定需要装配的组件的id,而不是使用属性名。
我们修改MyService类文件,将需要自动装配的mydao这个属性添加注解@Qualifier
。
MyService:
package com.xiaojian.service;
import com.xiaojian.dao.MyDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
public class MyService {
@Qualifier("myDao2") //此处通过@Qualifier指定装配myDao2,也就是指定装配通过@Bean注册的组件。
@Autowired
private MyDao myDao;
@Override
public String toString() {
return "MyService{" +
"myDao=" + myDao +
'}';
}
}
我们运行测试类Test_MainConfigOfAutowired,测试结果:
D:\basic\jdk\jdk1.8.0_131\bin\java ...
MyService{myDao=MyDao{label='2'}}
Process finished with exit code 0
如上,我们通过注解@Qualifier
指定自动配置中注入的内容的来源,此处就是来自IOC容器中通过@Bean
注册的bean对象。
@Primary
注解让spring进行自动装配的时候,默认使用首选的bean(如果使用了@Qualifier
注解指定了,那么就装配其指定的bean对象)。
我们将MainConfigOfAutowired配置类中的bean添加注解@Primary
,将其设置为首选的bean的配置。
MainConfigOfAutowired:
package com.xiaojian.config;
import com.xiaojian.dao.MyDao;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
@Configuration
@ComponentScan({"com.xiaojian.service","com.xiaojian.dao","com.xiaojian.controller"})
public class MainConfigOfAutowired {
//此处添加@Primary注解,将其设置为首选的bean注册
@Primary
@Bean("myDao2")
public MyDao myDao(){
MyDao myDao=new MyDao();
myDao.setLabel("2");
return myDao;
}
}
package com.xiaojian.service;
import com.xiaojian.dao.MyDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
@Service
public class MyService {
// @Qualifier("myDao2")
// @Autowired(required = false)
//此处还原成最原先的,不添加其他的任何注解
@Autowired
private MyDao myDao;
@Override
public String toString() {
return "MyService{" +
"myDao=" + myDao +
'}';
}
}
运行测试类Test_MainConfigOfAutowired,测试结果:
D:\basic\jdk\jdk1.8.0_131\bin\java ...
MyService{myDao=MyDao{label='2'}}
Process finished with exit code 0
如上,系统的控制台打印除了label=2这个,说明我们MyService中通过注解@Autowired
自动配置的MyDao是通过@Primay
注解注册的bean对象。
@Resource
自动注入(Java规范注解)package com.xiaojian.service;
import com.xiaojian.dao.MyDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class MyService {
// @Qualifier("myDao2")
// @Autowired(required = false)
// @Autowired
@Resource //此处添加@Resource
private MyDao myDao;
@Override
public String toString() {
return "MyService{" +
"myDao=" + myDao +
'}';
}
}
运行测试类Test_MainConfigOfAutowired,运行结果如下:
D:\basic\jdk\jdk1.8.0_131\bin\java ...
MyService{myDao=MyDao{label='1'}}
Process finished with exit code 0
如上,系统给MyService中添加了@Resource
注解的mydao
属性自动注入了通过@Repository
注入到IOC容器中的bean对象,而不是通过@Bean
注解注入到IOC容器中的bean对象。
@Resource
注解使用总结:
@Resource
可以实现自动装配的功能,但是其默认按照组件名称装配。@Primary
注解的功能,也没有支持@Autowired(required=false)
的功能@Repository
注解注入到IOC容器中的对象,而不是通过@Bean
注解注入到IOC容器中的bean对象。@Resource(name="xxxx")
来指定装配对象。@Resource(name = "myDao2")
@Inject
自动注入(Java规范注解)@Inject
注解的使用功能和@Autowired
注解是一样的。
我们想要使用这个注解,必须导入其他的相关的依赖。
<dependency>
<groupId>javax.injectgroupId>
<artifactId>javax.injectartifactId>
<version>1version>
dependency>
package com.xiaojian.service;
import com.xiaojian.dao.MyDao;
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;
@Service
public class MyService {
// @Qualifier("myDao2")
// @Autowired(required = false)
// @Autowired
// @Resource(name = "myDao2")
@Inject //此处使用@inject注解来自动注入
private MyDao myDao;
@Override
public String toString() {
return "MyService{" +
"myDao=" + myDao +
'}';
}
}
@primary
注解(因为我在MainConfigOfAutowired中没有改变,所以在bean对象的创建上面,我还是添加了@primary
注解)
运行测试类Test_MainConfigOfAutowired,测试结果:
D:\basic\jdk\jdk1.8.0_131\bin\java ...
MyService{myDao=MyDao{label='2'}}
Process finished with exit code 0
如上,此处打印的是label=2,说明此处注入的是MainConfigOfAutowired配置类中的bean方法创建的bean对象,因为我在此方法上面添加了@Primary
注解,所以才会打印这个。
@Primary
注解运行测试类Test_MainConfigOfAutowired,测试结果:
D:\basic\jdk\jdk1.8.0_131\bin\java ...
MyService{myDao=MyDao{label='1'}}
Process finished with exit code 0
如上,此处打印的是label=1,说明此处注入的是@Repository
注解注入的对象。