javaweb实训第五天上午——Spring基础(2)https://developer.aliyun.com/article/1415064
5.2.1.方案一:使用@Autowired
@Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired;
public class MyBean{ @Autowired //默认按照名称,名称找不到类型匹配 @Qualifier("otherBean1")//可以使用这个注解指定Bean的名称 private OtherBean otherBean; public void hello(){ otherBean.hello(); } } public class OtherBean{ public void hello(){ System.out.println("otherbean hello"); } } //xml配置: <bean id="otherBean" class="cn.cxjcloud.bean.OtherBean"></bean> <bean id="myBean" class="cn.cxjcloud.bean.MyBean"></bean>
5.2.2.方案二:使用@Resource
@Resource由J2EE提供,需要导入包javax.annotation.Resource,Spring支持该注解
public class MyBean{ @Resource //默认按照名字匹配【名字对了,类型也必须一致】,然后按照类型匹配 //@Resource(name="otherBean1")//指定Bean的名称 private OtherBean otherBean; public void hello(){ otherBean.hello(); } } public class OtherBean{ public void hello(){ System.out.println("otherbean hello"); } }
注意事项:在实例化Bean和注入Bean对象的同时,不要将xml方式和注解方式进行混用,要么都用xml方式【今天用】,要么都用注解方式【明天学完全注解就可以用了】;
6.Spring测试
6.1.Spring测试介绍
单元测试在我们的软件开发流程中占有举足轻重的地位;
而且目前基于Java 的企业应用软件来说,Spring 已经成为了标准配置,那么如何在Spring框架中更好的使用单元测试呢?
Spring框架提供了对单元测试(junit4)的强大支持,我们不用在使用传统的单元测试去测试Spring功能。通过SpringJunit测试,使用注解帮我们读取配置文件和赋值,简化测试代码,提高测试效率;
- 三大框架整合的时候如果Spring的配置文件不能读取,那么整个项目是跑不起来的, 而Spring的测试可以让我们在不启动服务器的情况下,使用注解读取相应的配置文件,把项目跑起来;
6.2.Spring测试步骤
第一步:导入相应的包
spring-test-4.1.2.RELEASE.jar -- 测试包 spring-aop-4.1.2.RELEASE.jar -- AOP包
注意:测试包依赖AOP,所以需要导入AOP的jar包,如果没有导入会报错:
第二步:编写测试类和方法
注解:
@RunWith:表示先启动Spring容器,把junit运行在Spring容器中;
@ContextConfiguration(“classpath:applicationContext.xml”):表示从CLASSPATH路径去加载资源文件;
@Autowired:表示自动装配,自动从Spring容器中取出对应bean赋值给当前使用的属性;Spring测试代码:
/** * @RunWith:代表开启Spring的测试 * SpringJUnit4ClassRunner:代表是Junit4的测试环境 * * @ContextConfiguration:找到我们的核心配置文件 * 特别注意这里路径: * 方式一(web工程,正式开发时使用): * /cn/cxjcloud/_02_test/applicationContext.xml → 从当前类所在包找(不建议使用) * classpath:cn/cxjcloud/_02_test/applicationContext.xml → 从classpath的根目录开始(正式开发) * 方式二(测试的时候使用): * applicationContext.xml → 当前类所在的包下面开始查找 * 方式三(测试的时候使用): * 注解后面不写名称 → 在当前目录下来创建xml的名称为:测试类名-Context.xml * 例:SpringTest-Context.xml。使用这种方式,这种写法好处是@ContextConfiguration可以不加参数 * * @author Administrator */ @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:applicationContext.xml") public class SpringTest { /** * 现在的测试环境应该是这样的 * Spring环境自行启动,所有的核心对象已经处于Spring之中,都应该由Spring自己来创建 * @Autowired的意思是自动注入,ApplcationContext这个类是Spring内部存在的,它也是一个Bean, * Spring可以把它创建出来,在它看到上面的这个标签后,再把创建的Bean注入进来 */ @Autowired private ApplicationContext context; /** * 这个TestBean我们已经在Spring中配置好。交给Spring来管理 * Spring即可以来创建这个对象,然后将这个对象赋值给这个成员变量 */ @Autowired private TestBean testBean; @Test public void testGetBean() throws Exception { System.out.println(testBean); } }
小结:Spring测试让测试变得更加简单,需要注意配置文件的位置,需要了解几个注解:
@RunWith(SpringJunit4ClassRunner.class)
@ContextConfiguration(“classpath:applicationContext.xml”)
@AutoWired
7.Spring配置细节
7.1.Bean对象的作用域
- 指的是我们配置的Bean是单例还是多例/原型
- 通过Bean元素中的scope属性指定:
singleton:默认值,单例
prototype:多例
<bean id="scopeBean" class="cn.cxjcloud._03_scope.MyScopeBean" scope="prototype"></bean>
3.其他属性值:(一般都不用)
7.2.Bean对象配置懒加载
1.Spring中所有bean对象全部懒加载:配置文件的根对象中添加default-lazy-init为true
<beans xmlns="http://www.springframework.org/schema/beans" 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" default-lazy-init="true"> </beans>
2.单个Bean对象懒加载/延迟加载
<bean id="user" class="cn.itdemo.test.User" lazy-init="true"></bean>
7.3.Bean对象的生命周期
Bean对象的生命周期指的是:从对象创建、初始化、调用执行到销毁的一个过程;
不同作用域的Bean,生命周期有所区别:
(1)Spring管理的Bean对象默认是单例的;
(2)Bean对象的实例化和初始化:
①实例化实质是Spring容器调用Bean的无参构造创建Bean对象;
②初始化实质上是Spring容器调用指定的初始化方法;
③BeanFactory管理的Bean默认是在使用的时候才创建Bean对象,即延迟加载,而AppliacationContext管理的Bean默认是在容器创建的时候就会创建Bean对象,即迫切加载;
(3)Bean对象的销毁:
①实质上是Spring容器调用指定的销毁方法(并不是真正意义上的销毁Bean对象);
②在容器关闭的时候(ApplicationContext对象没有close方法,其实现类有),Spring
容器会自动调用指定的销毁方法;
可以通过bean元素的init-method和destroy-method属性指定初始化方法和销毁方法。但是一般我们自己不会来配置这个生命周期。而这个基本上Spring自身来使用,例如在Spring操作连接池的时候,它会在DateSource销毁的时候执行;
8.三层架构中Spring的使用
8.1.三层构架回顾
三层架构咱们前面都已经给大家讲解过,咱们开发把整个操作分成三层:
8.2.三层架构规范
表现层设计:
Controller层:
|-- 无需接口(controller包) – XxxController – 例如:UserController
业务层设计: service层: |-- service接口(service包) -- IXxxService -- 例如:IUserService |-- service实现(service.impl包)-- XxxServiceImpl -- 例如:UserServiceImpl
持久化层设计: dao层: |-- dao接口(dao包) -- IXxxDAO -- 例如:IUserDAO |-- dao实现(dao.impl包) -- XxxDAOImpl -- 例如:UserDAOImpl
注意:一般一个domain对象对应一张表,一个dao组件,一个service组件,一个Controller组件;
8.3.三层架构中使用Spring
- 数据表和domain【User】
- 编写DAO层代码【IUserDao、UserDaoImpl-实现类中直接返回一个new的对象做测试】
- 业务层Service【IUserService、UserServiceImpl】
- 控制器Controller【UserServlet】
Web.xml配置
<!-- spring上下文监听器 --> <!-- ContextLoaderListener extends ContextLoader implements ServletContextListener --> <!-- 作用:ContextLoaderListener的作用就是启动Web容器时,读取在contextConfigLocation 中定义的xml文件,自动装配ApplicationContext的配置信息,并产生WebApplicationContext对象,【extends ApplicationContext】。这样我们只要得到Servlet就可以得到WebApplicationContext对象,并利用这个对象访问spring容器管理的bean。 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 加载sprin的 配置文件 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> Servlet中编写: @WebServlet("/get") public class UserController extends HttpServlet{ private ApplicationContext context; private IUserService service; @Override public void init() throws ServletException { System.out.println(111); if(context==null){ context=WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()); } service = context.getBean("service", UserServiceImpl.class); } }
5.部署测试
注意:使用WebApplicationContextUtils要导入web包;
9.课程总结
9.1.重点
- Spring是什么,有什么作用或好处;
- Spring编程;
- Spring依赖注入;
- Spring测试;
- Spring配置细节;
- 三层架构中Spring框架的使用;
9.2.难点
- Spring是什么,有什么作用或好处;
- Spring编程;
- Spring依赖注入;
- Spring测试;
- Spring配置细节;
- 三层架构中Spring框架的使用;
9.3.如何掌握?
- 课上认真听课;
- 完成课后练习;
- 抓住课程重点;
- 三层架构要多写几次,掌握熟练;
- 三层架构完成后再使用Spring来完成三层架构的注入;
9.4.排错技巧
- 通过异常和错误找出问题,分析问题,解决问题;
- Spring的测试注意路径问题(是否找到核心配置文件);
10.常见问题
11.课后练习
- 课堂代码1-2遍;
- 请写一个单例模式? (预计5分钟完成)
12.面试题
什么是Spring,Spring框架的作用是什么? (预计5分钟完成)
怎么理解IOC? (预计5分钟完成)
BeanFactory与ApplicationContext的区别? (预计5分钟完成)
三层架构是哪三层? 每一层是做什么的? 为什么要使用三层架构?(预计10分钟完成)
13.扩展阅读或课外阅读推荐(可选)
13.1.扩展知识
关于注解@Autowired和@Resource的匹配方式:
(1)@Autowired:默认按照类型【子类也可以】匹配,如果有多个类型一样的Bean,按照名字匹配,匹配不上报错
(2)@Resource:默认按照名字取匹配,但是类型必须对应