Spring框架基础

注册 PropertyPlaceholderConfigurer

Spring框架基础
Spring 2.5 之后: 可通过 context:property-placeholder 元素简化:
中添加 context Schema 定义
在配置文件中加入如下配置:
Spring框架基础

IOC 容器中 Bean 的生命周期方法

Spring IOC 容器可以管理 Bean 的生命周期, Spring 允许在 Bean 生命周期的特定点执行定制的任务.
Spring IOC 容器对 Bean 的生命周期进行管理的过程:
通过构造器或工厂方法创建 Bean 实例
为 Bean 的属性设置值和对其他 Bean 的引用
调用 Bean 的初始化方法
Bean 可以使用了
当容器关闭时, 调用 Bean 的销毁方法
在 Bean 的声明里设置 init-method 和 destroy-method 属性, 为 Bean 指定初始化和销毁方法.

注解

@Component: 基本注解, 标识了一个受 Spring 管理的组件
@Respository: 标识持久层组件
@Service: 标识服务层(业务层)组件
@Controller: 标识表现层组件

在 classpath 中扫描Bean

当在组件类上使用了特定的注解之后, 还需要在 Spring 的配置文件中声明 context:component-scan
base-package 属性指定一个需要扫描的基类包,Spring 容器将会扫描这个基类包里及其子包中的所有类.
当需要扫描多个包时, 可以使用逗号分隔.
如果仅希望扫描特定的类而非基包下的所有类,可使用 resource-pattern 属性过滤特定的类,示例:

<context:component-scan base-package="com.et">
<context:include-filter type=“annotation” expression=“org.*.stereotype.Service"/>
<context:exclude-filter type="assignable" expression="com.et.bean.Address"/>
</context:component-scan>

context:include-filter 子节点表示要包含的目标类
context:exclude-filter 子节点表示要排除在外的目标类

classpath 中扫描组件

context:include-filtercontext:exclude-filter 子节点支持多种类型的过滤表达式:
Spring框架基础

组件装配

context:component-scan 元素还会自动注册 AutowiredAnnotationBeanPostProcessor 实例, 该实例可以自动装配具有 @Autowired 和 @Resource 、@Inject注解的属性.

使用 @Autowired 自动装配 Bean

@Autowired 注解自动装配具有兼容类型的单个 Bean属性
构造器, 普通字段(即使是非 public), 一切具有参数的方法都可以应用@Authwired 注解
默认情况下, 所有使用 @Authwired 注解的属性都需要被设置. 当 Spring 找不到匹配的 Bean 装配属性时, 会抛出异常
, 若某一属性允许不被设置, 可以设置 @Authwired 注解的 required 属性为 false
默认情况下, 当 IOC 容器里存在多个类型兼容的 Bean 时, 通过类型的自动装配将无法工作. 此时可以在 @Qualifier 注解里提供 Bean 的名称. Spring 允许对方法的入参标注 @Qualifiter 已指定注入 Bean 的名称
@Authwired 注解也可以应用在数组类型的属性上, 此时 Spring 将会把所有匹配的 Bean 进行自动装配.
@Authwired 注解也可以应用在集合属性上, 此时 Spring 读取该集合的类型信息, 然后自动装配所有与之兼容的 Bean.
@Authwired 注解用在 java.util.Map 上时, 若该 Map 的键值为 String, 那么 Spring 将自动装配与之 Map 值类型兼容的 Bean, 此时 Bean 的名称作为键值

使用 @Resource 或 @Inject 自动装配 Bean

Spring 还支持 @Resource 和 @Inject 注解,这两个注解和 @Autowired 注解的功用类似
@Resource 注解要求提供一个 Bean 名称的属性,若该属性为空,则自动采用标注处的变量或方法名作为 Bean 的名称
@Resource是JDK自带的注解,耦合度低

@Inject 和 @Autowired 注解一样也是按类型匹配注入的 Bean, 但没有 reqired 属性
建议使用 @Autowired 注解

mavenMVC 加注解练习

Spring框架基础

pom文件装配

<dependencies>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>jstl</artifactId>
			<version>1.2</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>4.3.20.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.40</version>
		</dependency>
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.2</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>4.3.20.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet.jsp</groupId>
			<artifactId>javax.servlet.jsp-api</artifactId>
			<version>2.3.0</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>commons-dbutils</groupId>
			<artifactId>commons-dbutils</artifactId>
			<version>1.1</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.0.1</version>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.2</version>
		</dependency>
	</dependencies>
	<properties>
		<maven.compiler.source>1.8</maven.compiler.source>
		<maven.compiler.target>1.8</maven.compiler.target>
		<maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
	</properties>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.tomcat.maven</groupId>
				<artifactId>tomcat7-maven-plugin</artifactId>
				<version>2.2</version>
				<configuration>
					<uriEncoding>UTF-8</uriEncoding>
				</configuration>
			</plugin>
		</plugins>
	</build>

html

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="emp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
<style type="text/css">
	table{
		width:60%;
		border-collapse: collapse;
		text-align: center;
	}
	div {
		width:100%;
		margin-left:15%;
	}
	h1{
		text-align: center;
	}
	table td{
		border:1px solid green;
	}
	span{
		padding-left:20px;
		padding-right:20px;
	}
</style>
</head>
<body>
	<h1>员工信息查询表</h1>
	<div>
		<form action="${pageContext.request.contextPath}/listEmp">
			<p>员工姓名:<input type="text" name="ename" value="${requestScope.ename}">
			<input type="submit" value="查询">
		</form>
		<table>
			<tr>
				<td>员工编号</td>
				<td>员工姓名</td>
				<td>职位</td>
				<td>薪资</td>
				<td>部门编号</td>		
			</tr>
		<emp:forEach var="eml" items="${requestScope.pb.data}">
			<tr>
				<td>${eml.empno}</td>
				<td>${eml.ename}</td>
				<td>${eml.job}</td>
				<td>${eml.sal}</td>
				<td>${eml.deptno}</td>		
			</tr>
		</emp:forEach>
		</table>
		<p>
		<a href="listEmp?ename=${param.ename}&&curPage=${requestScope.pb.prePage}">上一页</a> 
		<emp:forEach var="i" begin="1" end="${requestScope.pb.totalPage}" step="1">
			<a href="listEmp?ename=${param.ename}&curPage=${i}">${i}</a>
		</emp:forEach>
		<span>总页数:${requestScope.pb.totalPage} </span>
		<span>当前页:${requestScope.pb.curPage} </span>
		<span>总条数:${requestScope.pb.total} </span> 
		<a href="listEmp?ename=${param.ename}&curPage=${requestScope.pb.nextPage}">下一页</a>
		
	</div>
</body>
</html>

Spring框架基础
contoller层

@WebServlet(urlPatterns="/listEmp")
public class EmpServlet extends HttpServlet{
	@Autowired
	private EmpService service;
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String ename=req.getParameter("ename");
		String curPage=req.getParameter("curPage");
		String pageNumber=req.getParameter("pageNumber");
		try {  
			service=MysqlUtil.cpac.getBean(EmpService.class);
			PageLimit<Emp> pb = service.queryEmp(ename,curPage,pageNumber);
			req.setAttribute("pb", pb);
			req.getRequestDispatcher("/emp.jsp").forward(req, resp);
		}  catch (Exception e) {
			e.printStackTrace();
		}
		
	}
}

dao层

public interface EmpDao {
	
	public int countEmp(String ename) throws Exception;
	
	List<Emp> queryEmp(String ename,int startIndex,int pageNumber) throws Exception;
}

public class EmpDaoImpl implements EmpDao{
	
	/**
	 * 分页展示
	 */
	public int countEmp(String ename) throws Exception {
		QueryRunner qr=new QueryRunner(MysqlUtil.bds);
		List<Emp> list;
		String sql="select count(*) as myCount from emp";
		if(StringUtils.isNotEmpty(ename)) {
			sql+=" where ename like '%"+ename+"%'";
		}
		Map map=(Map) qr.query(sql, new MapHandler());
		return Integer.parseInt(map.get("myCount").toString());
	}
	/**
	 * 查询emp表中的数据
	 */
	@Override
	public List<Emp> queryEmp(String ename,int startIndex,int pageNumber) throws Exception {
		QueryRunner qr=new QueryRunner(MysqlUtil.bds);
		List<Emp> list;
		String sql="select empno,ename,job,sal,deptno from emp";
		if(StringUtils.isNotEmpty(ename)) {
			sql+=" where ename like '%"+ename+"%'";
		}
		sql+=" limit "+startIndex+","+pageNumber;
		list = (List<Emp>) qr.query(sql, new BeanListHandler(Emp.class));
		return list;
	}

dbutils 数据库层

public class MysqlUtil {
	public static BasicDataSource bds;
	public static ClassPathXmlApplicationContext cpac;
	static {
		Properties pro=new Properties();
		cpac=new ClassPathXmlApplicationContext("classpath:prop.xml");
		bds=(BasicDataSource) cpac.getBean("dataSource"); 
	}
}

分页展示

public class PageLimit<T> {
	/**
	 * 
	 * @param curPage 当前页
	 * @param pageNumber  每页显示条数
	 * @param total	总共条数	
	 */
	public PageLimit(int curPage, int pageNumber,int total) {
		//计算上一页
		this.prePage=(curPage==1 ? 1 : curPage-1);
		//计算总页数
		this.totalPage=(total%pageNumber==0 ? total/pageNumber : total/pageNumber +1);
		//计算下一页
		this.nextPage=(curPage==totalPage ? totalPage : curPage+1);
		//当前页的索引
		this.startIndex=(curPage-1)*pageNumber;
		
		this.total=total;
		this.curPage=curPage;
		this.pageNumber=pageNumber;
	}
	
	/**
	 *  当前页 查询的默认当前页=1
	 *  页面传递的参数
	 */
	private int curPage;
	/**
	 * 每页显示数据, 默认数据8条
	 * 页面传递的参数
	 */
	private int pageNumber=2;
	/**
	 * 上一页
	 * 根据当前页计算
	 * if curPage==1 prePage=1       当前页是1的情况下 ,上一页是1 
	 * if curPage>1  prePage=curPage-1      当前页大于1的情况下 ,上一页是当前页-1
	 */
	private int prePage;
	/**
	 * 下一页
	 * if curPage==totalPage nextPage=totalPage  当前页是最后一页的情况下 ,下一页是最后一页
	 * if curPage<totalPage  nextPage=curPage+1        当前页小于最后一页的情况下 ,下一页是最后一页+1
	 */
	private int nextPage;
	/**
	 * 总共多少页
	 * 总条数tatal/每页显示的数据 pageNumber
	 * total%pageNumber==0 ? total/pageNumber : total/pageNumber +1
	 */
	private int totalPage;
	/**
	 * 总共多少条
	 * 数据库查询
	 */
	private int total;
	/**
	 * 开始索引
	 * (startIndex-1)*pageNumber
	 */
	private int startIndex;
	public int getStartIndex() {
		return startIndex;
	}
	public void setStartIndex(int startIndex) {
		this.startIndex = startIndex;
	}

	/**
	 * 转载当前页的数据
	 */
	private List<T> data;
	public int getCurPage() {
		return curPage;
	}
	public void setCurPage(int curPage) {
		this.curPage = curPage;
	}
	public int getPageNumber() {
		return pageNumber;
	}
	public void setPageNumber(int pageNumber) {
		this.pageNumber = pageNumber;
	}
	public int getPrePage() {
		return prePage;
	}
	public void setPrePage(int prePage) {
		this.prePage = prePage;
	}
	public int getNextPage() {
		return nextPage;
	}
	public void setNextPage(int nextPage) {
		this.nextPage = nextPage;
	}
	public int getTotalPage() {
		return totalPage;
	}
	public void setTotalPage(int totalPage) {
		this.totalPage = totalPage;
	}
	public int getTotal() {
		return total;
	}
	public void setTotal(int total) {
		this.total = total;
	}
	public List<T> getData() {
		return data;
	}
	public void setData(List<T> data) {
		this.data = data;
	}
	
}

属性bean

public class Emp {
	
	private String empno;//员工编号
	
	private String ename;//员工姓名
	
	private String job;//职位
	
	private String hiredate;//入职时间
	
	private String sal;//薪资
	
	private String deptno;//部门编号

	public String getEmpno() {
		return empno;
	}

	public void setEmpno(String empno) {
		this.empno = empno;
	}

	public String getEname() {
		return ename;
	}

	public void setEname(String ename) {
		this.ename = ename;
	}

	public String getJob() {
		return job;
	}

	public void setJob(String job) {
		this.job = job;
	}

	public String getHiredate() {
		return hiredate;
	}

	public void setHiredate(String hiredate) {
		this.hiredate = hiredate;
	}

	public String getSal() {
		return sal;
	}

	public void setSal(String sal) {
		this.sal = sal;
	}

	public String getDeptno() {
		return deptno;
	}

	public void setDeptno(String deptno) {
		this.deptno = deptno;
	}
}

service层

public interface EmpService {
	
	public PageLimit<Emp> queryEmp(String ename,String curPage,String pageNumber) throws Exception;
}
public class EmpServiceImpl implements EmpService{
	@Autowired
	private EmpDao dao;
			
	public PageLimit<Emp> queryEmp(String ename,String curPage,String pageNumber) throws Exception{
		//第一次访问 没有当前页
		if(StringUtils.isEmpty(curPage)) {
			curPage="1";
		}
		if(StringUtils.isEmpty(pageNumber)) {
			pageNumber="2";
		}
		//转换成int 类型
		int curPageIn=Integer.parseInt(curPage);
		int pageNumberIn=Integer.parseInt(pageNumber);
		int total=dao.countEmp(ename);
		PageLimit<Emp> pb=new PageLimit<>(curPageIn,pageNumberIn,total);
		List<Emp> queryEmp = dao.queryEmp(ename,pb.getStartIndex(),pb.getPageNumber());
		pb.setData(queryEmp);
		return pb;
	}
}

Spring框架基础
properties

jdbcDriver=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql://localhost:3306/unit02
jdbcUsername=root
jdbcPassword=******
<?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">
        
        
    <context:property-placeholder location="classpath:jdbc.properties"/>
    <context:component-scan base-package="com"></context:component-scan>
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    	<property name="driverClassName" value="${jdbcDriver}"></property> 
    	<property name="url" value="${jdbcUrl}"></property>
    	<property name="username" value="${jdbcUsername}"></property>
    	<property name="password" value="${jdbcPassword}"></property>
    </bean>
</beans>