Spring基础-03
BookDao.java:
import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Repository; /** * @Title: BookDao * @Description: id默认就是类名首字母小写 * @Author: * @Version: 1.0 * @create 2020/6/7 10:50 */ //@Repository("book")//修改bean名称为book @Repository //@Scope(value = "prototype") public class BookDao { public void saveBook(){ System.out.println("图书已经保存..."); } }
BookService.java:
import com.atguigu.dao.BookDao; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.Resource; /** * @Title: BookService * @Description: * @Author: * @Version: 1.0 * @create 2020/6/7 10:50 */ @Service public class BookService { // @Autowired @Resource private BookDao bookDao; public void save(){ System.out.println("bookService正在调用Dao帮你保存图书"); bookDao.saveBook(); } }
BookServiceExt.java:
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * @Title: BookServiceExt * @Description: * @Author: * @Version: 1.0 * @create 2020/6/7 11:49 */ @Service public class BookServiceExt extends BookService { @Autowired private BookDao bookDao; @Override public void save() { System.out.println("BookServiceExt被调用了..."); } }
BookController.java:
import com.atguigu.dao.BookDao; import com.atguigu.service.BookService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Controller; /** * 属性的自动注入 * @Autowired:spring会自动地为这个属性赋值 * 一定是去容器中找到这个属性对应的组件 */ @Controller public class BookController { //自动装配,自动地为这个属性赋值 //id为bookService //@Qualifier:指定一个名词作为id,让spring不要使用变量名 // @Qualifier("bookService") @Qualifier("bookServiceExt") // @Qualifier("bookServicehaha") @Autowired(required = false)//找不到装配null private BookService bookServiceExt2; public void doGet(){ // System.out.println("BookServlet..."+bookServiceExt2); bookServiceExt2.save(); } /** * 方法上有@Autowired的话 * 1)这个方法也会在bean创建的时候自动运行 * 2)这个方法上的每一个参数都会自动注入值 */@Autowired public void hahaha(BookDao bookDao,@Qualifier("bookServiceExt") BookService bookService){ System.out.println("Spring运行了这个方法..."+bookDao); System.out.println("Spring运行了这个方法..."+bookService); } }
applicationContext.xml:
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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"> 6 7 <!--通过注解分别创建Dao、Service、Controller★--> 8 <!--通过给bean上添加某些注解,可以快速地将bean加入到ioc容器中 9 某个类上添加任何一个注解都能快速地将这个组件加入到ioc容器的管理中 10 Spring有四个注解 11 @Controller:控制器 推荐给控制层(servlet包下的这些)的组件加这个注解 12 @Service:业务逻辑 推荐给业务逻辑层的组件添加这个注解 BookService 13 @Repository:给数据库层(持久化层,dao层)的组件添加这个注解 14 @Component:给不属于以上几层的组件添加这个注解 WebUtils 15 16 注解可以随便加:Spring底层不会去验证你的这个组件,是否如你注解所说就是一个dao层的或者servlet层的组件 17 我们推荐各自层加各自注解:给我们程序员看的 18 19 使用注解将组件快速地加入到容器中需要以下几步: 20 1)给要添加的组件标上四个注解中的任何一个 21 2)告诉Spring,自动扫描添加了注解的组件,依赖context名称空间 22 3)一定要导入aop包,支持加注解的模式 23 --> 24 25 <!--context:component-scan:自动组件扫描 26 base-package:指定扫描的基础包,把基础包及它下面所有的包下加了注解的类,自动扫描进ioc容器中 27 扫描要精确,不要只写com,这样会导致将系统的以com开头的jar包也扫入进去 28 --> 29 30 31 <!--注解和bean配置相结合--> 32 33 <!--使用context:include-filter指定扫描包时要包含的类 34 只扫描进入哪些组件,默认是全部扫描进来 35 一定要禁用掉默认的过滤规则才行:use-default-filters="false" 36 --> 37 <!--<context:component-scan base-package="com.atguigu" use-default-filters="false"> 38 <!–指定只扫描哪些组件–> 39 <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/> 40 <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/> 41 </context:component-scan>--> 42 43 <!--扫描的时候可以排除一些不要的组件 44 【type="annotation"】:指定排除规则,按照注解进行排除,标注了指定注解的组件不要 45 expression:注解的全类名 46 【type="assignable"】:排除某个具体的类,按照类排除 47 expression:类的全类名 48 type="aspectj":后来aspectj表达式 49 type="custom":自定义一个TypeFilter,自己写代码决定哪些是否使用 50 type="regex":还可以写正则表达式 51 (后三个几乎不用) 52 --> 53 54 <!--使用context:exclude-filter指定扫描包时不包含的类--> 55 <!--<context:component-scan base-package="com.atguigu"> 56 <!–<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>–> 57 <context:exclude-filter type="assignable" expression="com.atguigu.service.BookService"/> 58 </context:component-scan>--> 59 60 <!--DI依赖注入--> 61 <!--使用@Autowired注解实现根据类型实现自动装配★--> 62 <context:component-scan base-package="com.atguigu"></context:component-scan> 63 <!-- 64 @Autowired原理: 65 @Autowired 66 private BookService bookService; 67 1)先按照类型去容器中找到对应的组件:bookService = ioc.getBean(BookService.class); 68 2)两种情况: 69 1.找到一个:找到就赋值 70 2.没找到:抛异常 71 3.找到多个 72 ①按照变量名作为id继续匹配,BookService(bookService),BookServiceExt(bookServiceExt) 73 匹配上: 74 没有匹配上:继续报错 75 原因:因为我们按照变量名作为id继续匹配的 76 【使用@Qualifier("bookServiceExt")指定一个新id】 77 ①找到:装配 78 ②找不到:报错 79 80 发现:Autowired标注的自动装配的属性默认是一定装配上的 81 找到就装配,找不到就拉倒 @Autowired(required = false)//找不到装配null 82 --> 83 84 <!-- 85 实验19:如果资源类型的bean不止一个, 86 默认根据@Autowired注解标记的成员变量名作为id查找bean,进行装配★ 87 实验20:如果根据成员变量名作为id还是找不到bean, 88 可以使用@Qualifier注解明确指定目标bean的id★ 89 实验21:在方法的形参位置使用@Qualifier注解 90 实验22:@Autowired注解的required属性指定某个属性允许不被设置 91 --> 92 93 <!-- @Autowired、@Resource、@Inject:都是自动装配的意思 94 @Autowired:最强大,Spring自己的注解 95 @Resource:j2ee:java的标准 96 @Inject:EJB 97 面试题:@Autowired和@Resource区别 98 @Resource:扩展性更强:因为是java的标准。如果换成另外一个容器框架,@Resource还是可以使用的,但是@Autowired就不可以了 99 --> 100 101 </beans>
IOCTest.java:
import com.atguigu.controller.BookController;
import com.atguigu.service.BookService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
/**
* 使用Spring的单元测试
* 1.导包:Spring单元测试包 spring-test
* 2.@ContextConfiguration(locations = "")使用它来指定spring配置文件的位置
* 3.@RunWith指定用哪种驱动进行单元测试,默认就是Junit
*
* @RunWith(SpringJUnit4ClassRunner.class):使用spring的单元测试模块执行标注了@Test注解的测试方法 需要使用Junit4.12以上的版本
* 以前@Test注解只是有Junit执行
* 好处:我们不用ioc.getBean()获取组件了,直接@Autowired组件,Spring为我们自动装配
*/
@ContextConfiguration(locations = "classpath:applicationContext.xml")
@RunWith(SpringJUnit4ClassRunner.class)
public class IOCTest {
//ApplicationContext ioc = new ClassPathXmlApplicationContext("applicationContext.xml");
ApplicationContext ioc = null;
//使用spring单元测试后,直接注入即可,无需使用ioc.getBean("...")
@Autowired
BookController bookController;
@Autowired
BookService bookService;
/**
* 使用注解加入到容器中的组件和使用配置加入到容器中的组件行为默认都是一样的
* 1.组建的id:默认就是组件的类名首字母小写
*
* @Repository("book") 2.组件的作用域:默认就是单例的
* @Scope(value = "prototype")修改为多实例
*/
@Test
public void test() {
Object bookDao = ioc.getBean("bookDao");
Object bookDao2 = ioc.getBean("bookDao");
System.out.println(bookDao == bookDao2);//true
//Object book = ioc.getBean("book");
//System.out.println(book);
}
@Test
public void test02() {
BookController bean = ioc.getBean(BookController.class);
bean.doGet();
}
@Test
public void test03() {
}
@Test
public void test04() {
System.out.println(bookController);
}
}