目录
通过spring的注解完成对java对象的创建,属性的赋值,代替xml文件
ioc能够实现业务和对象之间的解耦合,例如service和dao对象之间的解耦合
常用注解:
<context:component-scan base-package="包名"/>
首先还是创建一个新的项目,在pom.xml文件中加入依赖
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.5.RELEASE</version> </dependency>
首先创建学生类
package com.md.b1; import org.springframework.stereotype.Component; /** * @author MD * @create 2020-08-08 15:51 * @Component: 创建对象的, 等同于<bean>的功能 * 属性:value 就是对象的名称,也就是bean的id值, * value的值是唯一的,创建的对象在整个spring容器中就一个 * 位置:在类的上面 * * @Component(value = "myStudent")等同于 * <bean id="myStudent" class="com.bjpowernode.ba01.Student" /> */ //@Component(value = "myStudent") // 省略value,常用 @Component("myStudent") // 不指定对象的名称,由spring默认提供:为类名首字母小写(student) //@Component public class Student { private String name; private Integer age; public Student() { System.out.println("我是Student的无参构造方法"); } public void setName(String name) { this.name = name; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
然后在spring的配置文件中applicationContext.xml加入组件扫描器
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> <!--声明组件扫描器,组件就是java对象 base-package:指定注解在你项目中的包名 component-scan工作方式:spring会扫描遍历base-package指定的包, 找包中以及子包中的所有的类,并找到类中的注解, 按照注解的功能创建对象,或者给属性赋值 --> <context:component-scan base-package="com.md.b1"/> </beans>
测试:
package com.md; import com.md.b1.Student; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * @author MD * @create 2020-08-08 16:05 */ public class MyTest01 { @Test public void test01(){ ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); // 从容器中获取对象 Student student = (Student) ac.getBean("myStudent"); System.out.println(student); } }
注意一:指定多个包的三种方式
<!--第一种方式:使用多次组件扫描器,指定不同的包--> <context:component-scan base-package="com.md.b1"/> <context:component-scan base-package="com.md.b2"/> <!--第二种方式:使用分隔符(;或,)分隔多个包名--> <context:component-scan base-package="com.md.b1;com.md.b2" /> <!--第三种方式:指定父包--> <context:component-scan base-package="com.md" />
重点:
注意二:spring中和@Component功能一致,创建对象的注解还有
以上三个注解的使用语法和@Component一样的。 都能创建对象,但是这三个注解还有额外的功能
@Repository,@Service,@Controller是给项目的对象分层的
某个类使用上面的三个注解都不合适的时候使用@Component
问题:创建对象的注解有几个,为什么有多个?
简单类型属性注入,需要在属性上使用注解@Value,该注解的 value 属性用于指定要注入的值
简单类型属性注入
使用该注解完成属性注入时,类中无需 setter。当然,若属性有 setter,则也可将其加到 setter 上
如下:
package com.md.b2; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * @author MD * @create 2020-08-08 15:51 */ @Component("myStudent") public class Student { /** * @Value: 简单类型的属性赋值 * 属性: value 是String类型的,表示简单类型的属性值 * 位置: 1.在属性定义的上面,无需set方法,推荐使用。 * 2.在set方法的上面 */ // @Value(value = "比比东") @Value("比比东") private String name; // @Value(value = "18") @Value("22") private Integer age; public Student() { System.out.println("我是Student的无参构造方法"); } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
<context:component-scan base-package="com.md.b2"/>
测试
@Test public void test01(){ ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); // 从容器中获取对象 Student student = (Student) ac.getBean("myStudent"); System.out.println(student); //我是Student的无参构造方法 //Student{name='比比东', age=22} }
byType自动注入
@Autowired:spring框架提供的注解,实现引用类型的赋值
需要在引用属性上使用注解@Autowired,该注解默认使用按类型自动装配Bean的方式(byType)
package com.md.b3; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * @author MD * @create 2020-08-08 16:39 */ @Component("student") public class Student { @Value("比比东") private String name; @Value("20") private Integer age; /** * 引用数据类型 * @Autowired:spring框架提供的注解,实现引用类型的赋值 * spring中通过注解给引用数据类型赋值的原理是使用自动注入,支持byName,byType * 默认使用的byType默认注入 * * 使用:在属性定义的上面,无需set方法,推荐 * 在set方法的上面 */ // 使用注解在School类里定义对象名称,以及属性值 或 使用bean的方式创建对象以及通过set方法给属性赋值 @Autowired private School school; @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", school=" + school + '}'; } }
School类
package com.md.b3; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; /** * @author MD * @create 2020-08-08 16:40 */ @Component("mySchool") public class School { @Value("交大") private String name; @Value("上海") private String address; @Override public String toString() { return "School{" + "name='" + name + '\'' + ", address='" + address + '\'' + '}'; } public void setName(String name) { this.name = name; } public void setAddress(String address) { this.address = address; } }
<context:component-scan base-package="com.md.b3"/>
测试和上面一样,就不写了,除了使用注解还可以使用xml的方式
这样就是可以的,
<bean id="school" class="com.md.b3.School"> <property name="name" value="上海交通大学"/> <property name="address" value="上海"/> </bean>
byName自动注入
由于@Autowired 默认使用的是byType,为了使用byName方式,
需要在引用属性上联合使用注解@Autowired 与@Qualifier
@Qualifier 的 value 属性用于指定要匹配的 Bean 的 id 值,
使用byName方式 1. 属性的上面加入@Autowired注解 2. 属性的上面加@Qualifier(value="bean的id")注解,表示使用指定名称的bean完成赋值 也就是使用这个对象来完成赋值
@Component("school") public class School { @Value("厦门大学") private String name; @Value("厦门") private String address; @Override public String toString() { return "School{" + "name='" + name + '\'' + ", address='" + address + '\'' + '}'; } }
Student类
@Component("student") public class Student { @Value("比比东") private String name; @Value("20") private Integer age; // 在School类里通过注解直接对象名为school @Autowired @Qualifier("school") private School school; @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", school=" + school + '}'; } }
属性:required ,是一个boolean类型的,默认true
例如:还是在上面的程序上
使用的是byName的方式,而此时失误bean的id写错了
@Component("student") public class Student { @Value("比比东") private String name; @Value("20") private Integer age; // 在School类里通过注解直接对象名为school @Autowired(required = false) @Qualifier("schoo") private School school; @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", school=" + school + '}'; } }
spring提供了对jdk中@Resource注解的支持。
@Resource注解既可以按名称匹配Bean,也可以按类型匹配 Bean。 默认是按名称注入(byName)
使用该注解,要求 JDK 必须是 6 及以上版本,@Resource 可在属性上,也可在 set 方法上
还是School类中
@Component("school") public class School { @Value("浙江大学") private String name; @Value("浙江") private String address; @Override public String toString() { return "School{" + "name='" + name + '\'' + ", address='" + address + '\'' + '}'; } }
此时Student类
@Component("student") public class Student { @Value("比比东") private String name; @Value("20") private Integer age; /** * 引用类型 * @Resource: 来自jdk中的注解,spring框架提供了对这个注解的功能支持,可以使用它给引用类型赋值 * 使用的也是自动注入原理,支持byName, byType .默认是byName * 位置: 1.在属性定义的上面,无需set方法,推荐使用。 * 2.在set方法的上面 */ //默认是byName: 先使用byName自动注入,如果byName赋值失败,再使用byType //@Resource // 若只使用byName方式,需要增加一个属性 name,name的值就是bean的id(对象名称) @Resource(name = "school") private School school; @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", school=" + school + '}'; } }
在spring的配置文件中applicationContext.xml加入组件扫描器
<context:component-scan base-package="com.md.b6"/>
@Test public void test01(){ ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); // 从容器中获取对象 Student student = (Student) ac.getBean("student"); System.out.println(student); // Student{name='比比东', age=20, school=School{name='浙江大学', address='浙江'}} }
注解优点是:方便、直观、高效(代码少,没有配置文件的书写那么复杂)
缺点:以硬编码的方式写入到 Java 代码中,修改是需要重新编译代码的
适合于不是经常修改的
XML 方式优点是:配置和代码是分离的、在 xml 中做修改,无需编译代码,只需重启服务器即可将新的配置加载
缺点:编写麻烦,效率低,大型项目过于复杂
原文链接:https://www.cnblogs.com/mengd/p/13472571.html