在Springboot整合SSM的基础上进行
SSM就应该用过下面三个了,我这主要说一下它们的用途
在进行下面内容看的时候如果目录结构搞不清可以回来看看,这个觉看着乱,那就看下面这个
画红圈的启动类和上面文件夹是平级的
package com.ssm.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
/**
* @author 作者
* @data 2019年8月2日
*/
@WebFilter(filterName = "myFilter", urlPatterns = "/*") //一个是filter的名字,一个是url为什么时用此过滤器,其他的看源码
public class MyFilter implements Filter{
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("这是我的Filter");
//放行
chain.doFilter(request, response);
}
}
//下面两个如果没有可以自己添加上,看源码,有这两个,只是不是必须的
@Override
public void destroy() {
}
@Override
public void init(FilterConfig arg0) throws ServletException {
}
Filter,必须要有名字,所有的过滤器执行顺序是根据Filter的名字字母顺序来执行的
注意:需要在springboot的运行类增加@ServletComponentScan
注解,添加上Filter的路径
示例:
@SpringBootApplication
@ServletComponentScan("com.ssm.filter")//这个是扫描包的路径
public class SpringBoot1Application {
public static void main(String[] args) {
SpringApplication.run(SpringBoot1Application.class, args);
}
}
如果不加@ServletComponentScan
就算这个类和运行类平级或者子级也不会被扫描上
需要添加依赖
org.springframework.boot
spring-boot-starter-aop
这做一个示例:对于controller 类里的所有方法进行拦截,拦截就让它进行日志管理吧,这篇博客只有AOP不需要在启动类上加
@ServletComponentScan
,其他两个都需要
AOP做日志管理的类
package com.ssm.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
/**
* @author 作者
* @data 2019年8月2日
*/
@Aspect //这两个注解必须有
@Component
public class MyAspect{
private final static Logger log = LoggerFactory.getLogger(MyAspect.class);
//定义切点位置:下面如果你在SSM中用AOP,在xml中配的就是下面
@Pointcut("execution(* com.ssm.controller..*.*(..))")
public void performance() {
}
/**
* 环绕通知记录时间
*
* @param joinPoint
* @return
* @throws Throwable
*/
@Around("performance()")
public Object doLog(ProceedingJoinPoint joinPoint) throws Throwable {
// 记录起始时间
long begin = System.currentTimeMillis();
Object result = "";
/** 执行目标方法 */
try {
result = joinPoint.proceed();
} catch (Exception e) {
log.error("日志记录发生错误, errorMessage: {}", e.getMessage());
} finally {
/** 记录操作时间 */
long took = (System.currentTimeMillis() - begin) / 1000;
log.info("controller执行时间为: {}秒", took);
}
System.out.println("66666666");
return result;
}
/**
* 前置通知
*
* @param joinPoint
* @throws Throwable
*/
@Before("performance()")
public void doBefore(JoinPoint joinPoint) throws Throwable {
// 接收到请求,记录请求内容
log.info("doBefore");
System.out.println("1111111");
}
}
不光只有上面这两个,总共有@Before
,@After
,@AfterReturning
,@AfterThrowing
,@Around
这五种
想知道他们的用法和想知道切点表达式怎么写,请参考Springboot(二十一)@Aspect 切面注解使用
启动类如果和上面的类平级或者和它父级平级,就不用在启动类上添加注解@ServletComponentScan
,它会自己扫描
自己写的注解
package com.ssm.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* @author 作者
* @data 2019年8月2日
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String operateDescription();// 记录日志的操作类型,不写默认值就是一个必须填的注解
}
AOP用手写注解做日志管理的类
package com.ssm.aop;
import java.lang.reflect.Method;
import java.sql.SQLException;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import com.ssm.annotation.MyAnnotation;
/**
* @author 作者
* @data 2019年8月2日
*/
@Aspect
@Component
public class MyAspect2 {
private final static Logger log = LoggerFactory.getLogger(MyAspect2.class);
/**
* 环绕通知处理
*
* @param pjp
* @return
* @throws Throwable
*/
@Around("@annotation(com.ssm.annotation.MyAnnotation)")
public Object aroundAdvice(ProceedingJoinPoint pjp) throws Throwable {
// 1.方法执行前的处理,相当于前置通知
// 获取方法签名
MethodSignature methodSignature = (MethodSignature) pjp.getSignature();
// 获取方法
Method method = methodSignature.getMethod();
// 获取方法上面的注解
MyAnnotation myAnno = method.getAnnotation(MyAnnotation.class);
// 获取到类名
String targetName = pjp.getTarget().getClass().getName();
// 获取到方法名字
String methodName = method.getName();
// 获取操作描述的属性值
String operateDescription = myAnno.operateDescription();
Object result = null;
try {
// 让代理方法执行
result = pjp.proceed();
// 2.相当于后置通知(方法成功执行之后走这里)
} catch (SQLException e) {
// 3.相当于异常通知部分
} finally {
// 4.相当于最终通知
log.info("class->{},methodName->{},operateDescription->{}", targetName, methodName, operateDescription);
}
System.out.println("基于手写注解的AOP拦截功能实现");
return result;
}
}
还有很多用途,不光这些,剩下的需要自己去发掘
多谢Springboot的日志管理&Springboot整合Junit测试&Springboot中AOP的使用
监听器类
package com.ssm.listener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* @author 作者
* @data 2019年8月2日
*/
@WebListener()
public class MyListener implements HttpSessionListener{
public static int online = 0;
@Override
public void sessionCreated(HttpSessionEvent se) {
System.out.println("创建session,在线用户数:" + (++online));
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
System.out.println("销毁session,在线用户数:" + (--online));
online--;
}
}
controller类
@Controller
public class UserController {
@Autowired
private UserService userService;
@RequestMapping("findAll")
public String findAll(Model model, HttpServletRequest request) throws Exception {
List list = userService.getAllUser();
model.addAttribute("list",list);
request.getSession().setAttribute("55", "55");
return "index";
}
}
启动类
@SpringBootApplication
@ServletComponentScan("com.ssm.listener") //需要扫描包
public class SpringBoot1Application {
public static void main(String[] args) {
SpringApplication.run(SpringBoot1Application.class, args);
}
}