spring入门篇4 --- IOC之注解
bean写法确实是很麻烦,如果项目比较大,那么写起来就会很麻烦
之前提到学习bean就是为了了解原理,现在学习一下注解注入的方法
首先看一下applicationContent.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 http://www.springframework.org/schema/context/spring-context.xsd"> <!--这个就是为了告知spring去扫描哪些文件--> <context:component-scan base-package="com.yang.*" /> </beans>
从这里面我们可以看到,已经没有bean的注入了,相反引入了context:component-scan,从名称可以看出,就是扫描组件,我们把需要扫描的位置告知即可
接下来看一下我们的第一个类
package com.yang.bean; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @Component // 这个标识符是为了告知spring,这个需要进行加载 @Scope(scopeName = "singleton") // 这个就是指定作用域,默认是singleton,单例模式 public class Person { @Value("1") // value就是这个属性进行初始化赋值,一般情况下是从配置中读取,现阶段先写死,为了学习 private int id; @Value("female") private String Sex; @Override public String toString() { return "Person{" + "id=" + id + ", Sex='" + Sex + '\'' + '}'; } }
从这里面可以看出已经没有setter方法了,也就是说注解并非通过setter方法进行赋值的。
@Component这个是告知Spring的需要扫描,但是Spring规定
- Service层使用@Service
- Controller层使用@Controller
- dao层使用@Respository
- 不知道什么层再使用@Component
但是这四个用法是完全一样的,没有什么本质区别,为什么这么写呢,这应该就是为了可以一眼看出来是什么层,别的没有太大分别
接下来看一下User
package com.yang.bean; 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.PostConstruct; import javax.annotation.PreDestroy; import javax.annotation.Resource; @Component // 注意,这个component可以指定名字,就跟bean的ID是一样的,默认是类名首字母小写,不会出现冲突,因为Spring是单例的 public class User { @Value("1") private int id; @Value("ming") private String name; // @Autowired // Autowired就是自动扫描该接口的实现类,如果只有一个成功,如果有多个会报错 // @Qualifier("person") // 这个一般搭配Autowired使用,如果一个接口有多个实现类,可以进行指定注入哪个实现类 @Resource(name = "person") // 这个就是Autowired + Qualifier(name)的组合,如果有多个实现类,可以指定,如果只有一个可以不指定 private Person person; public User() { } @PostConstruct // 这个就是初始化调用相当于bean中init-method public void init() { System.out.println("初始化"); } @PreDestroy // 这个是销毁方法,相当于destroy-method public void destroy() { System.out.println("销毁"); } public User(int id, String name) { this.id = id; this.name = name; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", person=" + person + '}'; } }
这个里面使用到自动注入功能,也就是Spring会扫描全局这种类型的对象,并为其注入与之匹配的
我们需要记得一定要在pom.xml中加入javax的annotation,这个里面有我们需要的一些注解
<!--这个是个注解模块--> <dependency> <groupId>javax.annotation</groupId> <artifactId>jsr250-api</artifactId> <version>1.0</version> </dependency>
最终看一下测试代码
package com.yang.test; import com.yang.bean.User; import org.junit.Test; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestUser { @Test public static void main(String[] args) { ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); User user = context.getBean("user", User.class); System.out.println(user); context.close(); } }
// 初始化
// User{id=1, name='ming', person=Person{id=1, Sex='female'}}
// 销毁
这个测试代码还是使用原始的测试方法,下一篇会使用注解方式,从测试代码可以看出,写法完全跟以前bean的一致,并且输出结果也符合预期