基于注解的DI入门程序
对于使用注解的DI,我们还需要引入aop jar包
在spring上,提供了两种注解的方式:
1.作用到类上的注解:创建对象
@Component:泛化的概念
@Controller:作用在控制层(Controller)的标识,表示当前的类是控制层
@Service:作用在业务逻辑层(Service)类上的标识,表示当前的类是业务逻辑层
@Respository:作用在持久层(DAO)类上的标识,表示当前的类是持久层
2.作用到成员变量上的注解:给成员变量赋值
@Value:给简单类型赋值
方式:1.注解定义在成员变量上,无须添加set方法,(推荐使用)
2.定义在set方法上(不常用)
@Autowried:用于实现引用类型的赋值,使用的是自动注入,支持byName,也支持byType(默认使用)
方式:1.添加到属性上面,无需添加set方法,(推荐使用)
2.添加到set方法上(不常用)
如果使用byName自动注入,添加一个注解@Qualifier(bean的id,也就是bean对象的名称)
@Autowried注解有一个属性required,默认是true,表示如果匹配失败,就会报错。
如果required=false,即便没有找到相对应的对象,系统也会继续执行,未匹配的属性值会被赋值为null。
@Resource:是JDK的注解,spring框架提供了对Resource注解的支持。可以用于实现对引用类型的赋值。
使用自动注入的方式去赋值,支持byName(默认),也支持byType
方式:1.定义在成员变量上,无需set方法(推荐使用)
2.定义在set方法上面(不常用)
@Resource注解是比较高级的,默认使用byName,但是如果没有找到相应的byName,就会再次使用byType去自动注入
使用@Component注解创建对象
需要用到的所有文件截图:
代码:applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 基于注解的配置文件 1.引入一个新的约束:spring-context.xsd 给约束一个命名空间和前缀 2.声明一个组件扫描器,组件是一个Java对象 component-scan:spring会根据base-package指定的包和子包去扫描, 找到加了注解的对象和成员变量,通过注解的不同,去完成对象的创建和成员变量的赋值的功能。 base-package:只当注解所在类的所属包名 --> <context:component-scan base-package="com.spring.anno.pg1"/> </beans>
对上面代码的说明:我们使用组件扫描器进行扫描的时候,会扫描com.spring.anno.pg1包下的所有的类,看一下有没有加入spring-component注解,如果加了注解,就会在spring容器中,创建一个类似于的语句,对象的名称就是bean语句中的id,也就是注解括号里面的内容,作为对象的名称。
User.java
package com.spring.anno.pg1; import org.springframework.stereotype.Component; @Component("user") public class User { private String name; private int age; @Override public String toString() { return "User [name=" + name + ", age=" + age + "]"; } }
对上面代码的说明:1.我们使用注解@Component("user")的方式去创建user对象,实际上就是在spring容器中写了这么一句话:
2.Component的属性值:唯一
如果Component没有属性值,创建的对象名是类名首字母小写的名字
测试文件:DIAnnoTest.java
package com.spring.anno.pg1; import java.util.Iterator; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class DIaAnnoTest { @Test public void test01() { String configLoction = "applicationContext.xml"; ApplicationContext ac = new ClassPathXmlApplicationContext(configLoction); String [] beanNames = ac.getBeanDefinitionNames(); for (String beanName : beanNames) { System.out.println(beanName); } System.out.println("------------------****************-----------------"); User user = (User) ac.getBean("user"); System.out.println(user); } }
使用注解给成员变量赋值
使用注解value定义在成员变量上赋值
这里我们使用value进行赋值,但是我们使用value给int赋值的时候,会出现错误,这里我们引用一下value的源码,按住ctrl点击value注解,找到spring-beans-4.3.16.RELEASE-sources.jar,打开之后,我们会看到这样一句话:
看选中的地方,value的类型是String,所以这里我们需要使用Value赋值的时候,如果赋值的类型是int类型,需要加上引号:
完整的程序代码(这里只给出和上面创建对象哪里需要改动的地方)
User.java
package com.spring.anno.pg1; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component //("myuser") //<bean id = " user" class = "User类的全限定名"/> //Component的属性值:唯一 //如果Component没有属性值,创建的对象名是类名首字母小写的名字 public class User { @Value("崔节壮") private String name; @Value("17") private int age; @Override public String toString() { return "User [name=" + name + ", age=" + age + "]"; } }
DIAnnoTest.java
package com.spring.anno.pg1; import java.util.Iterator; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class DIaAnnoTest { @Test public void test01() {//创建对象 String configLoction = "applicationContext.xml"; ApplicationContext ac = new ClassPathXmlApplicationContext(configLoction); String [] beanNames = ac.getBeanDefinitionNames(); for (String beanName : beanNames) { System.out.println(beanName); } System.out.println("------------------****************-----------------"); User user = (User) ac.getBean("user"); System.out.println(user); } @Test public void test02() {//赋值 String configLoction = "applicationContext.xml"; ApplicationContext ac = new ClassPathXmlApplicationContext(configLoction); User user = (User) ac.getBean("user"); System.out.println(user); } }
使用注解value定义set方法上赋值
这里赋值User.java,User2.java:
User2.java 代码:
package com.spring.anno.pg1; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component public class User2 { private String name; private int age; @Value("李四") public void setName(String name) { this.name = name; } @Value("19") public void setAge(int age) { this.age = age; } @Override public String toString() { return "User [name=" + name + ", age=" + age + "]"; } }
测试文件 DIAnnoTest.java
package com.spring.anno.pg1; import java.util.Iterator; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class DIaAnnoTest { @Test public void test01() { String configLoction = "applicationContext.xml"; ApplicationContext ac = new ClassPathXmlApplicationContext(configLoction); String [] beanNames = ac.getBeanDefinitionNames(); for (String beanName : beanNames) { System.out.println(beanName); } System.out.println("------------------****************-----------------"); User user = (User) ac.getBean("user"); System.out.println(user); } @Test public void test02() { String configLoction = "applicationContext.xml"; ApplicationContext ac = new ClassPathXmlApplicationContext(configLoction); User user = (User) ac.getBean("user"); System.out.println(user); } @Test public void test03() {//对User2使用set方法进行变量赋值 String configLoction = "applicationContext.xml"; ApplicationContext ac = new ClassPathXmlApplicationContext(configLoction); User2 user = (User2) ac.getBean("user2"); System.out.println(user); } }
使用注解Autowried实现引用类型的赋值:
代码 :
Address.java:
package com.spring.anno.pg3; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component("myaddress") public class Address { @Value("聊城阳谷县") private String addName; @Value("马湾村169号") private String addNo; @Override public String toString() { return "Address [addName=" + addName + ", addNo=" + addNo + "]"; } }
DIAnnoTest.java:
package com.spring.anno.pg3; import java.util.Iterator; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class DIaAnnoTest { @Test public void test01() { String configLoction = "applicationContext.xml"; ApplicationContext ac = new ClassPathXmlApplicationContext(configLoction); String [] beanNames = ac.getBeanDefinitionNames(); for (String beanName : beanNames) { System.out.println(beanName); } System.out.println("------------------****************-----------------"); User user = (User) ac.getBean("user"); System.out.println(user); } @Test public void test02() { String configLoction = "applicationContext.xml"; ApplicationContext ac = new ClassPathXmlApplicationContext(configLoction); User user = (User) ac.getBean("user"); System.out.println(user); } @Test public void test03() { String configLoction = "applicationContext2.xml"; ApplicationContext ac = new ClassPathXmlApplicationContext(configLoction); String [] beanNames = ac.getBeanDefinitionNames(); for (String beanName : beanNames) { System.out.println(beanName); } System.out.println("------------------****************-----------------"); User user = (User) ac.getBean("user"); System.out.println(user); } @Test public void test04() { String configLoction = "applicationContext3.xml"; ApplicationContext ac = new ClassPathXmlApplicationContext(configLoction); String [] beanNames = ac.getBeanDefinitionNames(); for (String beanName : beanNames) { System.out.println(beanName); } System.out.println("------------------****************-----------------"); User user = (User) ac.getBean("user"); System.out.println(user); } }
User.java:
package com.spring.anno.pg3; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component //("myuser") //<bean id = " user" class = "User类的全限定名"/> //Component的属性值:唯一 //如果Component没有属性值,创建的对象名是类名首字母小写的名字 public class User { @Value("崔节壮") //注解就相当于在spring容器中写了这么一句话: //<property name = "value注解的成员变量" value = "value注解的属性值"/ > private String name; @Value("17") private int age; @Autowired @Qualifier("myaddress") private Address address;//引用类型变量 @Override public String toString() { return "User [name=" + name + ", age=" + age + ", address=" + address + "]"; } }
applicationContext3.xml:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- 基于注解的配置文件 1.引入一个新的约束:spring-context.xsd 给约束一个命名空间和前缀 2.声明一个组件扫描器,组件是一个Java对象 component-scan:spring会根据base-package指定的包和子包去扫描, 找到加了注解的对象和成员变量,通过注解的不同,去完成对象的创建和成员变量的赋值的功能。 base-package:只当注解所在类的所属包名 --> <context:component-scan base-package="com.spring.anno.pg3 "/> </beans>
对注解@Autowried的说明:
我们点击进去,会看到这样一句话:(选中部分)
会看到required属性值,默认是true,我们在这里给他改成false:
之后我们进行测试一下,运行之后没有什么影响,我们进行一些改变:
Address.java
package com.spring.anno.pg3; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component("myaddress") public class Address { @Value("聊城阳谷县") private String addName; @Value("马湾村169号") private String addNo; @Override public String toString() { return "Address [addName=" + addName + ", addNo=" + addNo + "]"; } }
User.java
package com.spring.anno.pg3; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component //("myuser") //<bean id = " user" class = "User类的全限定名"/> //Component的属性值:唯一 //如果Component没有属性值,创建的对象名是类名首字母小写的名字 public class User { @Value("崔节壮") //注解就相当于在spring容器中写了这么一句话: //<property name = "value注解的成员变量" value = "value注解的属性值"/ > private String name; @Value("17") private int age; @Autowired(required = false) @Qualifier("address") private Address address;//引用类型变量 @Override public String toString() { return "User [name=" + name + ", age=" + age + ", address=" + address + "]"; } }
在Address.java中,创建的是myaddress对象,而在User.java当中,我们是给address对象赋值,并且把Autowired的属性值改为false,就不hi出现报错,找不到相应的对象,我们可以从我们人类的角度去看一下,我们创建了一个东西,结果找的时候找错名字了,按理说是找不到的,但是使用了一个超级牛逼的方式,不是报错了,而是这个东西没有找到,是输出出来,而不是直接一枪打死,这多人性化呀,对不对。
在新版的JDK中,取消了resource注解,我们使用的时候,需要自行导入resource的包。
使用resource注解进行自动注入
代码:
Address.java
package com.spring.anno.pg3; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @Component("address") public class Address { @Value("聊城阳谷县222") private String addName; @Value("马湾村169号") private String addNo; @Override public String toString() { return "Address [addName=" + addName + ", addNo=" + addNo + "]"; } }
User.java
package com.spring.anno.pg3; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import javax.annotation.Resource; @Component //("myuser") //<bean id = " user" class = "User类的全限定名"/> //Component的属性值:唯一 //如果Component没有属性值,创建的对象名是类名首字母小写的名字 public class User { @Value("崔节壮") //注解就相当于在spring容器中写了这么一句话: //<property name = "value注解的成员变量" value = "value注解的属性值"/ > private String name; @Value("17") private int age; @Resource private Address address;//引用类型变量 @Override public String toString() { return "User [name=" + name + ", age=" + age + ", address=" + address + "]"; } }
resource默认自动注入的byName,通过对象名称进行注入,所以在Address.java中,我们创建的对象名称是address的,但是我们把Address.java的创建的对象名称改为myaddress,同样也可以得到结果
需要添加一个包:
需要添加选中的包。