需要用到的注解有
1.用于创建对象的
* 他们的作用就和在XML配置文件中编写一个<bean>标签实现的功能是一样的 * @Component: * 作用:用于把当前类对象存入spring容器中 * 属性: * value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写。 * @Controller:一般用在表现层 * @Service:一般用在业务层 * @Repository:一般用在持久层 * 以上三个注解他们的作用和属性与Component是一模一样。 * 他们三个是spring框架为我们提供明确的三层使用的注解,使我们的三层对象更加清晰
2.用于注入数据的
* 他们的作用就和在xml配置文件中的bean标签中写一个<property>标签的作用是一样的 * @Autowired: * 作用:自动按照类型注入。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功 * 如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错。 * 如果Ioc容器中有多个类型匹配时,则需要用到@Qualifier * 出现位置: * 可以是变量上,也可以是方法上 * 细节: * 在使用注解注入时,set方法就不是必须的了。 * @Qualifier: * 作用:在按照类中注入的基础之上再按照名称注入。它在给类成员注入时不能单独使用。 但是在给方法参数注入时可以(稍后我们讲) * 属性: * value:用于指定注入bean的id。 * Resource * 作用:直接按照bean的id注入。它可以独立使用 * 属性: * name:用于指定bean的id。 * 以上三个注入都只能注入其他bean类型的数据,而基本类型和String类型无法使用上述注解实现。 * 另外,集合类型的注入只能通过XML来实现。 * * Value * 作用:用于注入基本类型和String类型的数据 * 属性: * value:用于指定数据的值。它可以使用spring中SpEL(也就是spring的el表达式) * SpEL的写法:${表达式}
3.用于改变对象的作用范围
* 他们的作用就和在bean标签中使用scope属性实现的功能是一样的 * Scope * 作用:用于指定bean的作用范围 * 属性: * value:指定范围的取值。常用取值:singleton prototype
4.用于改变对象的生命周期
* 和生命周期相关 了解 * 他们的作用就和在bean标签中使用init-method和destroy-methode的作用是一样的 * PreDestroy * 作用:用于指定销毁方法 * PostConstruct * 作用:用于指定初始化方法
以下是案例
1.创建maven项目,在pom.xml中添加spring约束
1 <?xml version="1.0" encoding="UTF-8"?> 2 <project xmlns="http://maven.apache.org/POM/4.0.0" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>com.cong</groupId> 8 <artifactId>spring_DI_anotation</artifactId> 9 <version>1.0-SNAPSHOT</version> 10 11 <packaging>jar</packaging> 12 <dependencies> 13 <dependency> 14 <groupId>org.springframework</groupId> 15 <artifactId>spring-context</artifactId> 16 <version>5.0.2.RELEASE</version> 17 </dependency> 18 19 </dependencies> 20 </project>
2.在java目录下创建com.cong.pojo.Pet类
1 package com.cong.pojo; 2 3 import org.springframework.beans.factory.annotation.Value; 4 import org.springframework.context.annotation.Scope; 5 import org.springframework.stereotype.Component; 6 7 import javax.annotation.PostConstruct; 8 import javax.annotation.PreDestroy; 9 10 @Component 11 @Scope("prototype")//改变对象的生命周期,常用的有两个singleton,prototype 12 public class Pet { 13 @Value("cat") 14 private String sname; 15 public void descPet(){ 16 System.out.println("person has a " + this.sname); 17 } 18 @PostConstruct//用于指定初始化方法 19 public void init(){ 20 System.out.println("初始化方法执行了..."); 21 } 22 @PreDestroy//用于指定对象的销毁方法 23 public void destroy(){ 24 System.out.println("销毁方法执行了..."); 25 } 26 }
3.在resources文件夹下添加bean.xml文件
打开spring开发包,按照目录打开framework-5.0.2.RELEASE -> docs -> spring-framework-reference,
找到index.html,用浏览器打开,点击【Core】,ctrl + f,搜索【xmlns:context】,红框中的就是我们这节注解方式的DI需要用到的
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:context="http://www.springframework.org/schema/context" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/context 8 http://www.springframework.org/schema/context/spring-context.xsd"> 9 <!--告知spring在创建容器时要扫描的包,配置所需要的标签不是在beans的约束中, 10 而是一个名称为context名称空间和约束中--> 11 <context:component-scan base-package="com.cong"></context:component-scan> 12 </beans>
4.在pojo文件夹下创建Person类
1 package com.cong.pojo; 2 3 import org.springframework.beans.factory.annotation.Autowired; 4 import org.springframework.beans.factory.annotation.Value; 5 import org.springframework.stereotype.Component; 6 7 /** 8 * 曾经XML的配置: 9 * <bean id="accountService" class="com.itheima.service.impl.AccountServiceImpl" 10 * scope="" init-method="" destroy-method=""> 11 * <property name="" value="" | ref=""></property> 12 * </bean> 13 * 14 * 用于创建对象的 15 * 他们的作用就和在XML配置文件中编写一个<bean>标签实现的功能是一样的 16 * Component: 17 * 作用:用于把当前类对象存入spring容器中 18 * 属性: 19 * value:用于指定bean的id。当我们不写时,它的默认值是当前类名,且首字母改小写。 20 * Controller:一般用在表现层 21 * Service:一般用在业务层 22 * Repository:一般用在持久层 23 * 以上三个注解他们的作用和属性与Component是一模一样。 24 * 他们三个是spring框架为我们提供明确的三层使用的注解,使我们的三层对象更加清晰 25 * 26 * 27 * 用于注入数据的 28 * 他们的作用就和在xml配置文件中的bean标签中写一个<property>标签的作用是一样的 29 * Autowired: 30 * 作用:自动按照类型注入。只要容器中有唯一的一个bean对象类型和要注入的变量类型匹配,就可以注入成功 31 * 如果ioc容器中没有任何bean的类型和要注入的变量类型匹配,则报错。 32 * 如果Ioc容器中有多个类型匹配时: 33 * 出现位置: 34 * 可以是变量上,也可以是方法上 35 * 细节: 36 * 在使用注解注入时,set方法就不是必须的了。 37 * Qualifier: 38 * 作用:在按照类中注入的基础之上再按照名称注入。它在给类成员注入时不能单独使用。但是在给方法参数注入时可以(稍后我们讲) 39 * 属性: 40 * value:用于指定注入bean的id。 41 * Resource 42 * 作用:直接按照bean的id注入。它可以独立使用 43 * 属性: 44 * name:用于指定bean的id。 45 * 以上三个注入都只能注入其他bean类型的数据,而基本类型和String类型无法使用上述注解实现。 46 * 另外,集合类型的注入只能通过XML来实现。 47 * 48 * Value 49 * 作用:用于注入基本类型和String类型的数据 50 * 属性: 51 * value:用于指定数据的值。它可以使用spring中SpEL(也就是spring的el表达式) 52 * SpEL的写法:${表达式} 53 * 54 * 用于改变作用范围的 55 * 他们的作用就和在bean标签中使用scope属性实现的功能是一样的 56 * Scope 57 * 作用:用于指定bean的作用范围 58 * 属性: 59 * value:指定范围的取值。常用取值:singleton prototype 60 * 61 * 和生命周期相关 了解 62 * 他们的作用就和在bean标签中使用init-method和destroy-methode的作用是一样的 63 * PreDestroy 64 * 作用:用于指定销毁方法 65 * PostConstruct 66 * 作用:用于指定初始化方法 67 */ 68 @Component(value = "person")//在注解中如果只有一个属性值,value是可以省略的,如多是多个,则不可以 69 public class Person { 70 @Value("001")//注入基本数据类型 71 private int pid; 72 @Value("cong")//注入String类型 73 private String pname; 74 @Value("男") 75 private String psex; 76 @Autowired//(name = "pet")//按照类型自动注入bean对象 77 private Pet pet; 78 public void showPet(){ 79 pet.descPet(); 80 } 81 82 @Override 83 public String toString() { 84 return "Person{" + 85 "pid=" + pid + 86 ", pname='" + pname + '\'' + 87 ", psex='" + psex + '\'' + 88 '}'; 89 } 90 }
5.在java文件夹下面创建com.cong.dao.Person接口
1 package com.cong.dao; 2 3 public interface PersonDao { 4 public void savePerson(); 5 }
6.在dao文件夹下面创建PersonDaoImpl类
1 package com.cong.dao; 2 3 import org.springframework.stereotype.Repository; 4 5 //没有写value属性,则默认的bean的id是personDaoImpl 6 @Repository 7 public class PersonDaoImpl implements PersonDao { 8 @Override 9 public void savePerson() { 10 System.out.println("save person..."); 11 } 12 }
7.在dao文件夹下创建PersonDao2类
1 package com.cong.dao; 2 3 import org.springframework.stereotype.Repository; 4 5 /** 6 * 第二个PersonDao实现类 7 */ 8 @Repository//没有写value属性,则默认的bean的id是personDaoImpl2 9 public class PersonDaoImpl2 implements PersonDao { 10 @Override 11 public void savePerson() { 12 System.out.println("save person...2"); 13 } 14 }
8.在java目录下创建com.cong.service.PersonService类
1 package com.cong.service; 2 3 import com.cong.dao.PersonDao; 4 import org.springframework.beans.factory.annotation.Autowired; 5 import org.springframework.beans.factory.annotation.Qualifier; 6 import org.springframework.stereotype.Service; 7 8 @Service//没有写value属性,则默认的bean的id是personService 9 public class PersonService { 10 @Autowired 11 @Qualifier("personDaoImpl2")//PersonDao有两个实现类,按照类型自动注入对象识别不了,借助@Qualifier注解 12 private PersonDao personDao; 13 public void savePerson(){ 14 personDao.savePerson(); 15 } 16 }
9.在java目录下创建com.cong.ui.Test类
1 package com.cong.ui; 2 3 import com.cong.pojo.Person; 4 import com.cong.pojo.Pet; 5 import com.cong.service.PersonService; 6 import org.springframework.context.support.ClassPathXmlApplicationContext; 7 8 public class Test { 9 public static void main(String[] args) { 10 // ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml"); 11 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean.xml"); 12 Person person = (Person) context.getBean("person"); 13 System.out.println(person.toString()); 14 person.showPet(); 15 PersonService ps = (PersonService) context.getBean("personService"); 16 ps.savePerson(); 17 18 Pet pet = (Pet) context.getBean("pet"); 19 Pet pet1 = (Pet) context.getBean("pet"); 20 System.out.println(pet == pet1);//false,因为是prototype 21 //pet对象设置了@Scope("prototype"),变成多例模式(默认是单例模式), 22 // 关闭了容器,对象也不会销毁 23 context.close(); 24 } 25 }
10.运行结果
11.完整目录