当前位置: 首页 > news >正文

潍坊网站制作厂家网络营销有哪些方式

潍坊网站制作厂家,网络营销有哪些方式,apache多网站配置,wordpress最常用水印spring AOP 基础定义 含义使用切面组织多个Advice,Advice放在切面中定义。也就是说是定义通知的自定义类。自定义的AOP类Aspect连接点方法调用,异常抛出可以增强的点JoinPoint :也就是**被增强的方法的总称,可以获取具体方法的信息&#xff…

spring AOP

img

基础定义

含义使用
切面组织多个Advice,Advice放在切面中定义。也就是说是定义通知的自定义类。自定义的AOP类@Aspect
连接点方法调用,异常抛出可以增强的点JoinPoint :也就是**被增强的方法的总称,可以获取具体方法的信息,然后执行他。一般和环绕通知一起使用**
通知/增强处理(Advice)around, befor, afterafter returing ,after throwing对其进行增强@Around(),获取连接点,然后前后执行增强代码
切入点被增强的方法,规定什么条件下可以增强@anotation():在有这个注解条件下增强execution():执行哪个接口方法,哪个包下方法的时候进行切入
目标
代理
织入增强代码和目标代码通过代理的方式加入到代理类中

举例-Redis分布式锁

这里实现一个基于注解的AOP实现

  • 首先定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface RedisLock {/*** 业务键** @return*/String key();/*** 锁的过期秒数,默认是5秒** @return*/int expire() default 5;/*** 尝试加锁,最多等待时间** @return*/long waitTime() default Long.MIN_VALUE;/*** 锁的超时时间单位** @return*/TimeUnit timeUnit() default TimeUnit.SECONDS;
}作者:pjmike_pj
链接:https://juejin.cn/post/6844903830442737671
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 其次定义AOP
// 1. 定义切面
@Aspect
@Component
public class LockMethodAspect {@Autowiredprivate RedisLockHelper redisLockHelper;@Autowiredprivate JedisUtil jedisUtil;private Logger logger = LoggerFactory.getLogger(LockMethodAspect.class);// 2. 定义通知为Aroud类型// 3. 定义使用@RedisLock来定义切入点@Around("@annotation(com.redis.lock.annotation.RedisLock)")public Object around(ProceedingJoinPoint joinPoint) {Jedis jedis = jedisUtil.getJedis();MethodSignature signature = (MethodSignature) joinPoint.getSignature();Method method = signature.getMethod();RedisLock redisLock = method.getAnnotation(RedisLock.class);String value = UUID.randomUUID().toString();String key = redisLock.key();// 4. 实现增强代码try {final boolean islock = redisLockHelper.lock(jedis,key, value, redisLock.expire(), redisLock.timeUnit());logger.info("isLock : {}",islock);if (!islock) {logger.error("获取锁失败");throw new RuntimeException("获取锁失败");}try {// 5. 执行目标代码return joinPoint.proceed();} catch (Throwable throwable) {throw new RuntimeException("系统异常");}}  finally {logger.info("释放锁");redisLockHelper.unlock(jedis,key, value);jedis.close();}}
}
  • 最后就可以使用了
@RestController
public class TestController {// 定义切入点@RedisLock(key = "redis_lock")@GetMapping("/index")public String index() {return "index";}
}
  • 辅助类
@Component
public class RedisLockHelper {private long sleepTime = 100;/*** 直接使用setnx + expire方式获取分布式锁* 非原子性** @param key* @param value* @param timeout* @return*/public boolean lock_setnx(Jedis jedis,String key, String value, int timeout) {Long result = jedis.setnx(key, value);// result = 1时,设置成功,否则设置失败if (result == 1L) {return jedis.expire(key, timeout) == 1L;} else {return false;}}/*** 使用Lua脚本,脚本中使用setnex+expire命令进行加锁操作** @param jedis* @param key* @param UniqueId* @param seconds* @return*/public boolean Lock_with_lua(Jedis jedis,String key, String UniqueId, int seconds) {String lua_scripts = "if redis.call('setnx',KEYS[1],ARGV[1]) == 1 then" +"redis.call('expire',KEYS[1],ARGV[2]) return 1 else return 0 end";List<String> keys = new ArrayList<>();List<String> values = new ArrayList<>();keys.add(key);values.add(UniqueId);values.add(String.valueOf(seconds));Object result = jedis.eval(lua_scripts, keys, values);//判断是否成功return result.equals(1L);}/*** 在Redis的2.6.12及以后中,使用 set key value [NX] [EX] 命令** @param key* @param value* @param timeout* @return*/public boolean lock(Jedis jedis,String key, String value, int timeout, TimeUnit timeUnit) {long seconds = timeUnit.toSeconds(timeout);return "OK".equals(jedis.set(key, value, "NX", "EX", seconds));}/*** 自定义获取锁的超时时间** @param jedis* @param key* @param value* @param timeout* @param waitTime* @param timeUnit* @return* @throws InterruptedException*/public boolean lock_with_waitTime(Jedis jedis,String key, String value, int timeout, long waitTime,TimeUnit timeUnit) throws InterruptedException {long seconds = timeUnit.toSeconds(timeout);while (waitTime >= 0) {String result = jedis.set(key, value, "nx", "ex", seconds);if ("OK".equals(result)) {return true;}waitTime -= sleepTime;Thread.sleep(sleepTime);}return false;}/*** 错误的解锁方法—直接删除key** @param key*/public void unlock_with_del(Jedis jedis,String key) {jedis.del(key);}/*** 使用Lua脚本进行解锁操纵,解锁的时候验证value值** @param jedis* @param key* @param value* @return*/public boolean unlock(Jedis jedis,String key,String value) {String luaScript = "if redis.call('get',KEYS[1]) == ARGV[1] then " +"return redis.call('del',KEYS[1]) else return 0 end";return jedis.eval(luaScript, Collections.singletonList(key), Collections.singletonList(value)).equals(1L);}
}

小结

  1. 定义切面,来承载通知和切点。
  2. 定义切点,什么情况下织入增强的代码。
  3. 定义通知/增强代码。
  4. 如果使用注解定义的切点,就给需要增强的连接点加上注解。如果需要增强某一个类的连接点,直接在切点中配置就行了。

代理模式

说到这里就需要说下代理模式以及spring使用的代理模式。

先说结论:

Java中有两种代理,一种是Proxy,另一种是cglib代理。proxy需要接口,cglib代理不需要。因为proxy使用了反射机制,而cglib直接通过ASM操作字节码文件。

JVM层面看代理模式

  • cglib代理

cglib代理通过操作字节码文件把增强代码加入到原来目标类中,从而生成一个新的类,然后载入到内存中,这就是代理类

  • 通过反射的代理:
  1. 定义接口
  2. 实现接口方法
  3. 使用proxy包裹接口,定义钩子函数handler实现增强代码,返回被代理类。
  4. 其中的handler一般会调用被代理类的方法。

而这个调用方法,是使用反射生成的一个被代理对象。

  • 反射的原理:

类加载之后,会在内存中存入Class列表,也就是类定义列表在内存是一种hash结构,全类名到类定义方法区的映射。所以通过全类名可以得到对应的类定义,然后生成对象。

http://www.hkea.cn/news/406530/

相关文章:

  • 国外建设工程招聘信息网站tool站长工具
  • 专业做相册书的网站电商网站建设制作
  • 银川网站开发公司电话东莞网
  • 环境保护局网站管理制度建设百度指数的主要功能有
  • 安装wordpress提示500错误关键词优化的策略有哪些
  • 企业网站建设公司排名深圳高端seo公司助力企业
  • 做网站套餐网站seo
  • 网站上的代码网页怎么做的下载百度软件
  • 网站功能模块建设搜狗推广
  • 网站做推广有用吗网站页面设计
  • 做简报的网站广州搜发网络科技有限公司
  • 南乐县住房和城乡建设局网站制作网站的步骤是什么
  • 金华做网站最专业的公司搜易网提供的技术服务
  • wordpress适合门户网站吗怎么营销自己的产品
  • 常用的网站类型有哪些seo优化专员编辑
  • 网站专题框架怎么做海阳seo排名
  • 手机网站代码下载黄页网站推广服务
  • 做网站前端多少钱在线bt种子
  • wordpress+模版+推荐专业网站seo推广
  • 浦项建设公司员工网站2023免费推广入口
  • 如何查询某个网站的设计公司最新推广注册app拿佣金
  • 八宝山做网站公司打广告
  • wordpress vip查看插件南宁seo费用服务
  • 建站之星模板怎么设置手机如何做网站
  • 上海公司网站制作价格西安百度关键词排名服务
  • 长沙网页制作开发公司aso优化方案
  • 深圳罗湖网站制作成人电脑基础培训班
  • 无锡网站制作咨询深圳网站设计十年乐云seo
  • 大连城市建设网站seo优化顾问服务阿亮
  • 福州 网站建设沈阳seo关键词排名优化软件