1. Spring整合Mybatis
1.1 实现目标
以用户登录为例,实现Spring与Mybatis的整合
1.2 实现流程
1.2.1 创建登录页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String path = request.getContextPath();
String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + path + "/";
%>
<html>
<head>
<base href="<%=basePath%>">
<title>登录页面</title>
</head>
<body>
<div align="center">
<form action="login" method="post">
<h2>欢迎使用</h2>
<hr/>
<table>
<tr>
<th>用户名</th>
<th><input type="text" name="uname"/></th>
</tr>
<tr>
<th>密码</th>
<th><input type="password" name="pwd"/></th>
</tr>
<tr>
<th colspan="2"> <input type="submit" value="登录"/></th>
</tr>
</table>
</form>
</div>
</body>
</html>
1.2.2 导入jar包
1.2.2.1 JDBC的jar包
1.2.2.2 Mybatis的jar包
1.2.2.3 Spring IOC的jar包
1.2.2.4 Spring 整合Mybatis的jar包
1.2.3 创建pojo实体类
package cn.khue.pojo;
public class User {
private String uname;
private String pwd;
public User() {
}
public User(String uname, String pwd) {
this.uname = uname;
this.pwd = pwd;
}
public String getUname() {
return uname;
}
public void setUname(String uname) {
this.uname = uname;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "User{" +
"uname='" + uname + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
}
1.2.4 创建mapper接口
package cn.khue.mapper;
import cn.khue.pojo.User;
public interface UserMapper {
@Select("select * from user where uname=#{0} and pwd=#{1}")
User login(String uname, String pwd);
}
1.2.5 创建service接口
package cn.khue.service;
import cn.khue.pojo.User;
public interface UserService {
User login(String uname, String pwd);
}
1.2.6 创建service实现类
package cn.khue.service;
import cn.khue.mapper.UserMapper;
import cn.khue.pojo.User;
public class UserServiceImpl implements UserService {
private UserMapper mapper;
public UserMapper getMapper() {
return mapper;
}
public void setMapper(UserMapper mapper) {
this.mapper = mapper;
}
@Override
public User login(String uname, String pwd) {
return mapper.login(uname,pwd);
}
}
1.2.7 创建servlet类
package cn.khue.servlet;
import cn.khue.pojo.User;
import cn.khue.service.UserService;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/login")
public class UserServlet extends HttpServlet {
private UserService service;
@Override
public void init() throws ServletException {
WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
service= (UserService) wac.getBean("userService");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
String uname = req.getParameter("uname");
String pwd = req.getParameter("pwd");
User user = service.login(uname, pwd);
if(null != user){
resp.getWriter().write("<div align='center'><h2>登录成功</h2></div>");
}else{
resp.getWriter().write("<div align='center'><h2>登录失败</h2></div>");
}
}
}
1.2.8 修改web.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationcontext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
1.2.9 创建log4j.properties文件
log4j.rootCategory=FATAL, CONSOLE,LOGFILE
log4j.logger.cn.khue.mapper=debug
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.Threshold=DEBUG
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=-%p-%l-%d{yyy MMM dd HH:mm:ss}-%m%n
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=D:/axis.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.Threshold=DEBUG
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=-%p-%c-%M-%l-%d{yyy MMM dd HH:mm:ss}-%m%n
1.2.10 创建applicationcontext配置文件
<?xml version="1.0" encoding="UTF-8"?>
<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">
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</bean>
<bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="mapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="cn.khue.mapper"/>
<property name="sqlSessionFactory" ref="factory"/>
</bean>
<bean id="userService" class="cn.khue.service.UserServiceImpl">
<property name="mapper" ref="userMapper"/>
</bean>
</beans>
1.3 最终效果
2. Spring AOP
2.1 解决的问题
在不修改原有功能代码的基础上实现功能的扩展
2.2 AOP的关键词
2.2.1 Aspect
Aspect是指切面,通常表现为类,在该类里面可以定义切入点及通知
2.2.2 Pointcut
Pointcut是指切点
2.2.3 JoinPoint
JoinPoint是指连接点
2.2.4 Advice
Advice是指通知或增强,表现为Pointcut内定义具体的功能扩展代码
Advice可以分为一下几种
2.2.4.1 Before
前置通知,在执行目标方法之前运行
2.2.4.2 After
后置通知,在执行目标方法之后运行
2.2.4.3 AfterReturning
返回通知,在执行目标方法正常返回值之后运行
2.2.4.4 AfterThrowing
异常通知,在执行目标方法出现异常后运行
2.2.4.5 Around
环绕通知,等同于Before+After
2.2.5 Weaving
Weaving是指织入,表示将Aspect和其他对象连接起来,并创建Aspect对象的整个过程
2.3 实现方式
2.3.1 导入jar包
2.3.1.1 Spring IOC的jar包
2.3.1.2 Spring AOP的jar包
2.3.1.3 logging的jar包
2.3.1.4 AOP命名空间依赖的jar包
2.3.2 Schema-Based方式
2.3.2.1 创建目标方法
package cn.khue.pojo;
public class Target {
public void target(){
System.out.println("\033[36m"+"这是目标方法"+"\033[m");
}
}
2.3.2.2 创建测试类
package cn.khue.test;
import cn.khue.pojo.Target;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
Target target = (Target) ac.getBean("target");
target.target();
}
}
2.3.2.3 创建扩展功能类
package cn.khue.advice;
import org.springframework.aop.AfterAdvice;
public class MyAfter implements AfterAdvice {
public void after(){
System.out.println("\033[36m"+"这是后置通知"+"\033[m");
}
}
package cn.khue.advice;
import org.springframework.aop.AfterReturningAdvice;
import java.lang.reflect.Method;
public class MyAfterReturning implements AfterReturningAdvice {
@Override
public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
System.out.println("\033[36m"+"这是返回通知"+"\033[m");
}
}
package cn.khue.advice;
import org.springframework.aop.ThrowsAdvice;
public class MyAfterThrowing implements ThrowsAdvice {
public void afterThrowing(Exception e) throws Throwable{
System.out.println("\033[36m"+"这是异常通知"+"\033[m");
e.printStackTrace();
}
}
package cn.khue.advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class MyAround implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("\033[36m"+"这是环绕前通知"+"\033[m");
Object obj = methodInvocation.proceed();
System.out.println("\033[36m"+"这是环绕后通知"+"\033[m");
return obj;
}
}
package cn.khue.advice;
import org.springframework.aop.MethodBeforeAdvice;
import java.lang.reflect.Method;
public class MyBefore implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] objects, Object o) throws Throwable {
System.out.println("\033[36m"+"这是前置通知"+"\033[m");
}
}
2.3.2.4 创建Spring配置文件
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--配置bean-->
<bean id="target" class="cn.khue.pojo.Target"/>
<bean id="before" class="cn.khue.advice.MyBefore"/>
<!-- <bean id="after" class="cn.khue.advice.MyAfter"/>-->
<bean id="around" class="cn.khue.advice.MyAround"/>
<bean id="throw" class="cn.khue.advice.MyAfterThrowing"/>
<bean id="return" class="cn.khue.advice.MyAfterReturning"/>
<!--配置切面-->
<aop:config>
<aop:pointcut id="targets" expression="execution(* cn.khue.pojo.Target.target())"/>
<aop:advisor advice-ref="before" pointcut-ref="targets"/>
<!-- <aop:advisor advice-ref="after" pointcut-ref="targets"/>-->
<aop:advisor advice-ref="return" pointcut-ref="targets"/>
<aop:advisor advice-ref="throw" pointcut-ref="targets"/>
<aop:advisor advice-ref="around" pointcut-ref="targets"/>
</aop:config>
</beans>
2.3.3 AspectJ方式
2.3.3.1 创建目标方法
package cn.khue.pojo;
public class Target {
public void target(){
System.out.println("\033[36m"+"这是目标方法"+"\033[m");
}
}
2.3.3.2 创建测试类
package cn.khue.test;
import cn.khue.pojo.Target;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
Target target = (Target) ac.getBean("target");
target.target();
}
}
2.3.3.3 创建扩展功能类
package cn.khue.advice;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyAdvice {
public void before(){
System.out.println("\033[36m"+"这是前置通知"+"\033[m");
}
public void after(){
System.out.println("\033[36m"+"这是后置通知"+"\033[m");
}
public void afterReturning(){
System.out.println("\033[36m"+"这是返回通知"+"\033[m");
}
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("\033[36m"+"这是环绕前通知"+"\033[m");
Object obj = pjp.proceed();
System.out.println("\033[36m"+"这是环绕后通知"+"\033[m");
return obj;
}
public void afterThrowing(Exception e){
System.out.println("\033[36m"+"这是异常通知"+"\033[m"+e.getMessage());
}
}
2.3.2.4 创建Spring配置文件
<?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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--配置bean-->
<bean id="target" class="cn.khue.pojo.Target"/>
<bean id="advice" class="cn.khue.advice.MyAdvice"/>
<!--配置切面-->
<aop:config>
<aop:aspect ref="advice">
<aop:pointcut id="targets" expression="execution(* cn.khue.pojo.Target.target())"/>
<aop:before method="before" pointcut-ref="targets"/>
<aop:after method="after" pointcut-ref="targets"/>
<aop:after-returning method="afterReturning" pointcut-ref="targets"/>
<aop:after-throwing method="afterThrowing" pointcut-ref="targets" throwing="e"/>
<aop:around method="around" pointcut-ref="targets"/>
</aop:aspect>
</aop:config>
</beans>
2.3.4 注解方式
2.3.4.1 创建目标方法
package cn.khue.pojo;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component
public class Target {
@Pointcut("execution(* cn.khue.pojo.Target.target())")
public void target(){
System.out.println("\033[36m"+"这是目标方法"+"\033[m");
// int i=5/0;
}
}
2.3.4.2 创建测试类
package cn.khue.test;
import cn.khue.pojo.Target;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationcontext.xml");
Target target = (Target) ac.getBean("target");
target.target();
}
}
2.3.4.3 创建扩展功能类
package cn.khue.advice;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class MyAdvice {
@Before("cn.khue.pojo.Target.target()")
public void before(){
System.out.println("\033[36m"+"这是前置通知"+"\033[m");
}
@After("cn.khue.pojo.Target.target()")
public void after(){
System.out.println("\033[36m"+"这是后置通知"+"\033[m");
}
@AfterReturning("cn.khue.pojo.Target.target()")
public void afterReturning(){
System.out.println("\033[36m"+"这是返回通知"+"\033[m");
}
@Around("cn.khue.pojo.Target.target()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("\033[36m"+"这是环绕前通知"+"\033[m");
Object obj = pjp.proceed();
System.out.println("\033[36m"+"这是环绕后通知"+"\033[m");
return obj;
}
@AfterThrowing(value = "cn.khue.pojo.Target.target()",throwing = "e")
public void afterThrowing(Exception e){
System.out.println("\033[36m"+"这是异常通知"+"\033[m"+e.getMessage());
}
}
2.3.4.4 创建Spring配置文件
<?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:aop="http://www.springframework.org/schema/aop"
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/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--声明注解扫描-->
<context:component-scan base-package="cn.khue.pojo,cn.khue.advice"/>
<!--开启aop注解支持-->
<aop:aspectj-autoproxy expose-proxy="true"/>
</beans>