AOP、FIFO(先进先出)算法、阻塞式队、执行链、枚举、反射注解、定时任务、线程池、处理程序拦截器、堵塞异常处理程序

AOP

不修改源码的基础上对对象功能扩展
OCP开闭原则
默认CGLib代理
方式一:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

/**
 * @Aspect注解描述的类我们称之为切面对象,此对象负责定义切入点和通知
 * 1)切入点(在哪些方法执行时我们进行功能扩展-锦)
 * 2)通知(所有的扩展逻辑都会写到通知方法中-花)
 */
 @Order(2) //越小越优先
@Aspect	//生成代理对象
@Component
public class LogAspect {
    /**
     * 通过@Pointcut注解定义定义切入点表达式,表达式的写法有多种,比较常用
     * 有注解方式的表达式(@annotation(你自己定义的注解)).当使用自己写
     * 的注解对方法进行描述时,这个方法就是切入点方法.在这个方法上要锦上添花
     */
    @Pointcut("@annotation(com.jyx.aop.RequiredLog)")
    public void doLog(){}//这个方法没有意义,主要用于承载切入点

    /**
     * Around通知,在此通知内部可以定义我们扩展业务逻辑,还可以调用目标执行链
     * @param joinPoint 连接点(通知方法与目标方法的连接点对象),ProceedingJoinPoint
     *   类型的连接点只能应用在Around通知方法中.
     * @return
     * @throws Throwable
     */
    @Around("doLog()")
    public Object doAround(ProceedingJoinPoint joinPoint)
    throws Throwable{
         System.out.println("Before:"+System.currentTimeMillis());
         Object result=joinPoint.proceed();//执行链(其它切面,目标对象方法)
         System.out.println("After:"+System.currentTimeMillis());
         return result;
    }

}

自定义注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequiredLog {
    String operation() default "";
}

方式二:

 @Order(2) //越小越优先
@Aspect		//生成代理对象
@Component
public class LogAspect {
	 //语法结构: execution([权限修饰符] [返回类型] [类全路径] [方法名称]([参数列表]) )	
	 //对包里面所有类,类里面所有方法进行增强
	@Before ("execution(* com.jyx.*.*(..))") //(* com.jyx.*.*(..))返回值类型、所有类、所有方法
											//也可以@Pointcut(value = "execution(* com.jyx.*.*(..))")
	 public void doLog(){}
	

FIFO(先进先出)算法


/**
 * Cache 接口规范设计
 */
public interface Cache {
    /**
     * 存储数据
     * @param key
     * @param value
     */
    void putObject(Object key,Object value);

    /**
     * 基于key获取数据
     * @param key
     * @return
     */
    Object getObject(Object key);

    /**
     * 移除指定key的数据
     * @param key
     * @return
     */
    Object removeObject(Object key);

    /**
     * 清空缓存
     */
    void clear();

    /**
     * 获取缓存中数据的个数
     * @return
     */
    int size();
    //...
}


import java.util.Deque;
import java.util.LinkedList;

/**
 * 有界缓存淘汰策略:FIFO(先进先出)算法
 */
public class FifoCache implements Cache{
    /**存储数据的Cache*/
    private Cache cache;
    /**Cache的最大容量*/
    private int maxCap;
    /**双端队列(两头都可以操作),基于此队列记录key的顺序*/
    private Deque<Object> deque;
    public FifoCache(Cache cache, int maxCap) {
        this.cache = cache;
        this.maxCap = maxCap;
        this.deque=new LinkedList<>();
    }
    @Override
    public void putObject(Object key, Object value) {
        //1.记录key的顺序
        deque.addLast(key);
        //2.判定cache是否已满,满了则移除元素
        //if(cache.size()==maxCap){} 方式1
        if(deque.size()>maxCap){//方式2
            //获取最先放入的元素key
            Object eldestKey=deque.removeFirst();
            //移除最先放进去的元素
            cache.removeObject(eldestKey);
        }
        //3.添加新的元素
        cache.putObject(key,value);
    }
    @Override
    public Object getObject(Object key) {
        return cache.getObject(key);
    }

    @Override
    public Object removeObject(Object key) {
        Object value=cache.removeObject(key);
        deque.remove(key);
        return value;
    }

    @Override
    public void clear() {
        cache.clear();
        deque.clear();
    }

    @Override
    public int size() {
        return cache.size();
    }

    @Override
    public String toString() {
        return "FifoCache{" +
                "cache=" + cache +
                '}';
    }

    public static void main(String[] args) {
        FifoCache cache = new FifoCache(new DefaultCache(), 3);
        cache.putObject("A",100);
        cache.putObject("B",200);
        cache.putObject("C",300);
        cache.putObject("D",400);
        cache.putObject("E",500);
        System.out.println(cache);
    }
}

阻塞式队列

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

/**
 * 阻塞式队列
 */
public class BlockQueueTests {
    public static void main(String[] args) throws InterruptedException {
        //FIFO(先进先出-体现公平性):类似超市排队结账
        //1.对象构建
        BlockingQueue<Integer> queue=
                new ArrayBlockingQueue<Integer>(2);
                //new LinkedBlockingQueue<>(5);
        //2.存储数据
        queue.add(100);
        queue.add(200);
        System.out.println(queue);//100,200
        //queue.add(300);//抛出异常
        queue.put(300);//满了则阻塞

        //System.out.println(queue);//输出不了
        System.out.println(queue.remove());
        System.out.println(queue.remove());
        //System.out.println(queue.remove());//抛出异常
        Integer result=queue.take();//阻塞式方法,空则阻塞
        System.out.println("result="+result);

    }
}

执行链

import java.util.ArrayList;
import java.util.List;

/**拦截器*/
interface Interceptor{
    boolean doPre();
    void doPost();
}
/**处理器*/
interface Handler{
    void doHandle();
}
/**
 * 执行链设计(所有项目中的执行(Execution)链(Chain)都是预先设计好的)
 */
class ExecutionChain{
    //拦截器是边缘业务
    private List<Interceptor> interceptors;
    //处理器是核心业务
    private Handler handler;
    public ExecutionChain(List<Interceptor> interceptors, Handler handler) {
        this.interceptors = interceptors;
        this.handler = handler;
    }

    //执行业务逻辑
    public void execute(){//proceed()
        //1.执行拦截器(Interceptor)中的doPre方法
        for(int i=0;i<interceptors.size();i++)
             interceptors.get(i).doPre();
        //2.执行处理器(Handler)中的doHandle方法
        handler.doHandle();
        //3.执行拦截器(Interceptor)中的doPost方法
        for(int i=interceptors.size()-1;i>=0;i--)
            interceptors.get(i).doPost();
    }

}
public class ExecutionChainTests {
    public static void main(String[] args) {
        List<Interceptor> interceptors=new ArrayList<>();
        interceptors.add(new Interceptor() {
            @Override
            public boolean doPre() {
                System.out.println("doPre1");
                return false;
            }

            @Override
            public void doPost() {
                System.out.println("doPost1");
            }
        });
        interceptors.add(new Interceptor() {
            @Override
            public boolean doPre() {
                System.out.println("doPre2");
                return false;
            }

            @Override
            public void doPost() {
                System.out.println("doPost2");
            }
        });
        Handler handler=()-> {
            System.out.println("执行任务...");
        };
        ExecutionChain chain=new ExecutionChain(interceptors,handler);
        chain.execute();
    }

}

枚举

import java.util.concurrent.TimeUnit;

//枚举类型JDK5推出一种新的数据类型,主要用于定义一些固定值.
//一年四季
//一周七天
//订单状态
//性别要求
enum Gender{//Gender.class
    //定义三个枚举实例(类加载时创建)
    MALE,FEMALE,NONE("没有性别要求");
    private String name;
    private Gender(){}
    private Gender(String name){
        this.name=name;
    }
    public String getName(){
        return this.name;
    }
}
class Product{
    //性别要求
    Gender gender=Gender.NONE;
}

public class EnumTests {
    public static void main(String[] args) throws InterruptedException {
        String name = Gender.NONE.getName();
        System.out.println("name="+name);
        TimeUnit.SECONDS.sleep(3);
    }
}

反射注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Method;

//自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface GetMapping{//GetMapping.java-->GetMapping.class
    String value() default "";
}
//接口定义
interface RemoteService{
    @GetMapping("/service/hello")
    String call(String msg);
}
public class AnnotationTests {
    public static void main(String[] args) throws NoSuchMethodException {
        //1.反射的入口
        Class<RemoteService> remoteServiceClass = RemoteService.class;
        //2.获取方法对象
        Method call =
        remoteServiceClass.getDeclaredMethod("call", String.class);
        //3.获取方法对象上的注解
        GetMapping annotation = call.getAnnotation(GetMapping.class);
        //4.获取注解中value属性
        String value=annotation.value();
        System.out.println(value);
    }
}

定时任务

public class TimerTests {
    public static void main(String[] args) {
        //通过timer对象可以启动一个定时任务
        Timer timer=new Timer();
        //基于timer对象启动并执行任务
        timer.schedule(new TimerTask() {//这是一个任务对象
            @Override
            public void run() {
                System.out.println(System.currentTimeMillis());
            }
        },1000,//1秒以后开始执行
                1000);//每隔1秒执行1次


    }
}

线程池

package com.jt.thread;
//J.U.C
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;

public class ThreadPoolTests {
    public static void main(String[] args) {
//         public ThreadPoolExecutor(int corePoolSize,
//        int maximumPoolSize,
//        long keepAliveTime,
//        TimeUnit unit,
//        BlockingQueue<Runnable> workQueue)
        //1.核心线程数
        int corePoolSize=2;
        //2.最大线程数
        int maximumPoolSize=3;
        //3.线程最大空闲时间
        long keepAliveTime=60;
        //4.时间单位(枚举-1.5)
        TimeUnit unit=TimeUnit.SECONDS;
        //5.任务队列(阻塞式队列)
        BlockingQueue<Runnable> workQueue=
                new ArrayBlockingQueue<>(1);

        //6.定义拒绝策略(可选,常用有四种)
        RejectedExecutionHandler handler=
                //当池无法处理这个任务时,由任务启动方去执行任务
                new ThreadPoolExecutor.CallerRunsPolicy();
        //7.构建线程工厂(可选,最关键是要给线程一个友好的名字)
        ThreadFactory factory=new ThreadFactory() {
            //线程名前缀
            private String namePrefix="cgb-2015-thread-";
            //构建一个线程安全的原子自增自减对象
            private AtomicLong atomicLong= new AtomicLong(1);
            @Override
            public Thread newThread(Runnable r) {//r 为任务
                return new Thread(r,namePrefix+atomicLong.getAndIncrement());
            }
        };
        //8.创建线程池
        ThreadPoolExecutor pool=
                new ThreadPoolExecutor(
                        corePoolSize,
                        maximumPoolSize,
                        keepAliveTime,
                        unit,
                        workQueue,
                        factory,
                        handler);
        //7.将任务交给池中对象去执行
        pool.execute(new Runnable() {
            @Override
            public void run() {
                String tName=
                Thread.currentThread().getName();
                System.out.println(tName+"->任务1");
                try{Thread.sleep(5000);}catch (Exception e){}
            }
        });
        pool.execute(new Runnable() {
            @Override
            public void run() {
                String tName=
                        Thread.currentThread().getName();
                System.out.println(tName+"->任务2");
                try{Thread.sleep(5000);}catch (Exception e){}
            }
        });
        pool.execute(new Runnable() {
            @Override
            public void run() {
                String tName=
                        Thread.currentThread().getName();
                System.out.println(tName+"->任务3");
                try{Thread.sleep(5000);}catch (Exception e){}
            }
        });
        pool.execute(new Runnable() {
            @Override
            public void run() {
                String tName=
                        Thread.currentThread().getName();
                System.out.println(tName+"->任务4");
                try{Thread.sleep(5000);}catch (Exception e){}
            }
        });
        pool.execute(new Runnable() {
            @Override
            public void run() {
                String tName=
                        Thread.currentThread().getName();
                System.out.println(tName+"->任务5");
            }
        });

        pool.shutdown();//不再接收任务,等现有任务执行结束将池关掉
       // pool.shutdownNow();//不再接收任务,但有可能会将现有任务也会停止
    }
}

处理程序拦截器

@Configuration
public class SpringWebConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注册拦截器,并且设置要拦截的路径
        registry.addInterceptor(new TimeInterceptor())
                .addPathPatterns("/demo/");//要拦截的路径
    }
}

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.time.LocalTime;

@Component
public class TimeInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("==preHandler==");
        LocalTime now=LocalTime.now();//JDK8中的时间对象
        int hour=now.getHour();//获取当前时间对应小时
        System.out.println("hour="+hour);
        if(hour<=6||hour>=17)
            throw new RuntimeException("请在6~17点进行访问");
        return true;//false表示请求到此结束,true表示执行执行链中的下一个对象
    }

}

import com.jt.aop.RequiredLog;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/demo/")
public class DemoController {//--->Controller--->Service--->Dao
    @RequiredLog //由此注解描述的方法就是切入点方法
    @GetMapping
    public String doSayHello(){
        //System.out.println("Before:"+System.currentTimeMillis());
        System.out.println("==doSayHello==");
        String result="hello spring";
        //System.out.println("After:"+System.currentTimeMillis());
        return result;
    }
}

堵塞异常处理程序

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;


@Component
public class ServiceBlockExceptionHandler implements BlockExceptionHandler {
    @Override
    public void handle(HttpServletRequest httpServletRequest,
                       HttpServletResponse httpServletResponse,
                       BlockException e) throws Exception {
        //1.设置响应数据编码
        httpServletResponse.setCharacterEncoding("utf-8");
        //2.告诉浏览器你要输出的数据类型及编码
        httpServletResponse.setContentType("text/html;charset=utf-8");
        PrintWriter writer = httpServletResponse.getWriter();
        writer.println("<h1>服务维护中</h1>");
        writer.flush();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值