首页 文章 精选 留言 我的

精选列表

搜索[Java],共10000篇文章
优秀的个人博客,低调大师

Java AOP(面向切面编程)实现

动态代理 AOP概念解释 AOP用在哪些方面:AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任,例如事务处理、日志管理、权限控制,异常处理等,封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。 AOP中的概念 Aspect(切面):指横切性关注点的抽象即为切面,它与类相似,只是两者的关注点不一样,类是对物体特征的抽象,而切面是横切性关注点的抽象。joinpoint(连接点):所谓连接点是指那些被拦截到的点(可以是方法、属性、或者类的初始化时机(可以是Action层、Service层、dao层))。在Spring中,这些点指的是方法,因为Spring只支持方法类型的连接点,实际上joinpoint还可以是field或类构造器。Pointcut(切入点):所谓切入点是指我们要对那些joinpoint进行拦截的定义,也即joinpoint的集合。Advice(通知):所谓通知是指拦截到joinpoint之后所要做的事情就是通知。通知分为前置通知、后置通知、异常通知、最终通知、环绕通知。我们就以CGlibProxyFactory类的代码为例进行说明: public class CGlibProxyFactory implements MethodInterceptor { private Object targetObject; // 代理的目标对象 public Object createProxyInstance(Object targetObject) { this.targetObject = targetObject; Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(this.targetObject.getClass()); // 设置目标类为代理对象的父类 enhancer.setCallback(this); return enhancer.create(); } // 从另一种角度看: 整个方法可看作环绕通知 @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { PersonServiceBean bean = (PersonServiceBean)this.targetObject; Object result = null; if (bean.getUser() != null) { // 有权限 // ...... advice() ----> 前置通知(所谓通知,就是我们拦截到业务方法之后所要干的事情) try { result = methodProxy.invoke(targetObject, args); // 把方法调用委派给目标对象 // ...... afteradvice() ----> 后置通知 } catch (RuntimeException e) { // ...... exceptionadvice() ----> 异常通知 } finally { // ...... finallyadvice() ----> 最终通知 } } return result; } } Target(目标对象):代理的目标对象。Weave(织入):指将aspects应用到target对象并导致proxy对象创建的过程称为织入。Introduction(引入):在不修改类代码的前提下,Introduction可以在运行期为类(代理类)动态地添加一些方法或Field。 AOP带来的好处:降低模块的耦合度;使系统容易扩展;更好的代码复用性。 2. JDK实现 1). 创建Person接口 public interface PersonService { /** * 保存 * @param name 名称 */ public void save(String name); /** * 根据ID更新名称 * @param name 姓名 * @param personId 人员ID */ public void update(String name, Integer personId); /** * 根据ID获取名称 * @param personId 人员ID * @return 名称 */ public String getPersonName(Integer personId); } 2). 创建实现Person接口的实现类PersonImpl public class PersonServiceImpl implements PersonService{ private String user = null; public void setUser(String user) { this.user = user; } public String getUser() { return user; } public PersonServiceImpl() { } public PersonServiceImpl(String user){ this.user = user; } @Override public void save(String name) { System.out.println("我是save方法"); } @Override public void update(String name, Integer personId) { System.out.println("我是update方法"); } @Override public String getPersonName(Integer personId) { System.out.println("我是getPersonName方法"); return "xxx"; } } 3). 创建代理类PersonServiceImplProxy public class PersonServiceImplProxy implements InvocationHandler { private PersonService personService; public PersonService createProxy(PersonService personService) { return (PersonService) Proxy.newProxyInstance(PersonServiceImplProxy.class.getClassLoader(), personService.getClass().getClass().getInterfaces(), this); } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { PersonServiceImpl pImpl = (PersonServiceImpl) this.personService; Object result = null; // 如果不等于null则表示有权限 if (null != pImpl.getUser()) { // 执行方法 result = method.invoke(personService, args); } return result; } } 4). 创建Demo类测试 public class Demo { public static void main(String[] args) { PersonServiceImplProxy proxy = new PersonServiceImplProxy(); PersonService service = proxy.createProxy(new PersonServiceImpl("mazaiting")); service.save("123"); } } 打印结果: 图1.png 5). 更改测试代码 public class Demo { public static void main(String[] args) { PersonServiceImplProxy proxy = new PersonServiceImplProxy(); PersonService service = proxy.createProxy(new PersonServiceImpl()); service.save("123"); } } 打印结果: 图2.png 3. CGlib实现AOP功能 动态代理技术只能是基于接口,那如果这个对象没有接口,就要使用CGlib这个工具包。 1). 创建PersonService类 public class PersonService { private String user = null; public void setUser(String user) { this.user = user; } public String getUser() { return user; } public PersonService() { } public PersonService(String user){ this.user = user; } public void save(String name) { System.out.println("我是save方法"); } public void update(String name, Integer personId) { System.out.println("我是update方法"); } public String getPersonName(Integer personId) { System.out.println("我是getPersonName方法"); return "xxx"; } } 2). 创建CGlibProxyFactory类 public class CGlibProxyFactory implements MethodInterceptor { // 代理的目标对象 private Object targetObject; public Object createProxyInstance(Object targetObject) { this.targetObject = targetObject; // 该类用于生成代理对象 Enhancer enhancer = new Enhancer(); // 设置目标类为代理对象的父类 enhancer.setSuperclass(this.targetObject.getClass()); // 设置回调用对象本身 enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { PersonService service = (PersonService) this.targetObject; Object result = null; // 有权限 if (null != service.getUser()) { // 把方法调用委派给目标对象 result = methodProxy.invoke(targetObject, args); } return result; } } 3). 创建Demo测试类 public class Demo { public static void main(String[] args) { CGlibProxyFactory factory = new CGlibProxyFactory(); PersonService service = (PersonService) factory.createProxyInstance(new PersonService("mazaiting")); service.save("999"); } } 4). 打印结果 图3.png

优秀的个人博客,低调大师

JAVA库函数总结【持续更新】

生成随机数: Math.random()是令系统随机选取大于等于 0.0 且小于 1.0 的伪随机 double 值. Random rand = newRandom(); rand.nextInt(int s);//生成0~s内的整数 int randNumber =rand.nextInt(MAX - MIN + 1) + MIN;//生成指定范围的整数 关于web服务获取服务器ip、hostname: 1. string ip = Request.ServerVariables["Remote_Addr"]; string ip = Request.UserHostAddress; 2. InetAddress addr = InetAddress.getLocalHost(); ip=addr.getHostAddress().toString;//获得本机IP address=addr.getHostName()toString;//获得本机名称

优秀的个人博客,低调大师

java或判断优化小技巧

写业务代码的时候,我们经常要做条件判断,有的时候条件判断的或判断长达20多个。reg.equals("1") || reg.equals("2") || reg.equals("3")||.....是不是很奔溃 1,这个时候代码维护不好维护,字段一多对字段就会出错。 2,在最差情况下,执行语句要对这20个判断都判断一下才知道最终的结果,在高性能业务下发挥并不好。 这个时候我们可以用map或set来进行判断,因为hashmap是一个hash桶,查找的效率是比较快的,不管判断任何值他的查询效率基本稳定。 当然最好指定hashmap的长度和判断的元素一样多,这样就避免对某一个桶内衍生出链表了。 例子如下,大家可以试一试。 /** * @author:YangLiu * @date:2018年3月22日 上午10:06:25 * @describe: */ public class ifMap { public static Map<String, String> ISJACARD = new HashMap<String, String>(20) { { put("1", ""); put("2", ""); put("3", ""); put("4", ""); put("5", ""); put("6", ""); put("7", ""); put("8", ""); put("9", ""); put("11", ""); put("12", ""); put("13", ""); put("14", ""); put("15", ""); put("16", ""); put("17", ""); put("18", ""); put("19", ""); put("21", ""); put("22", ""); put("23", ""); put("24", ""); put("25", ""); put("26", ""); put("27", ""); put("28", ""); put("29", ""); } }; public static void main(String[] args) { String reg = "13"; long start = System.currentTimeMillis(); for (int i = 0; i < 100000000; i++) { if (reg.equals("1") || reg.equals("2") || reg.equals("3") || reg.equals("4") || reg.equals("5") || reg.equals("6") || reg.equals("7") || reg.equals("8") || reg.equals("9") || reg.equals("19") || reg.equals("18") || reg.equals("17") || reg.equals("16") || reg.equals("15") || reg.equals("14") || reg.equals("13") || reg.equals("12") || reg.equals("11")) { } } System.out.println(System.currentTimeMillis() - start); start = System.currentTimeMillis(); for (int i = 0; i < 100000000; i++) { if (ISJACARD.containsKey(reg)) { } } System.out.println(System.currentTimeMillis() - start); } } 作者: intsmaze(刘洋) 出处: http://www.cnblogs.com/intsmaze/ 老铁,你的--->推荐,--->关注,--->评论--->是我继续写作的动力。 微信公众号号:Apache技术研究院 由于博主能力有限,文中可能存在描述不正确,欢迎指正、补充! 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

优秀的个人博客,低调大师

java基础学习_常用类小结

看看下面的类,是否都熟悉,简要说明每个类主要是干什么呢? Object:是类层次结构的根类,所有类都直接或者间接的继承自该类。 Scanner:获取键盘录入数据的类。 String:针对字符串的常见操作的类。 StringBuffer/StringBuilder:字符串缓冲区类,提高字符串的操作效率。 Arrays:针对数组进行操作的工具类。 Integer:把int基本数据类型封装成Integer引用数据类型,可以调用方法了,最主要作用是可以把String引用数据类型转换int基本数据类型了。 Character:把char基本类型封装成Character引用数据类型,可以调用方法了。了解几个方法就可以了。 Pattern:正则表达式的编译表示形式。模式对象。 Matcher:匹配器对象。 Math:针对数学运算操作的类。 Random:产生随机数的类。 System:系统类,提供了几个有用方法。 BigInteger:关于大整数的运算的类。 BigDecimal:关于浮点数的运算用这个,不会有精度的丢失。 Date:针对日期操作的类,可以精确到毫秒。 DateFormat:针对日期进行格式化或者针对字符串(文本)进行解析的类。 Calendar:日历类,把所有的日历字段(成员变量)进行了封装,要什么,自己使用获取方法,然后拼接。 Object:是类层次结构的根类,所有类都直接或者间接的继承自该类。 Scanner:获取键盘录入数据的类。 String:针对字符串的常见操作的类。 StringBuffer/StringBuilder:字符串缓冲区类,提高字符串的操作效率。 Arrays:针对数组进行操作的工具类。 Integer:把int基本数据类型封装成Integer引用数据类型,可以调用方法了,最主要作用是可以把String引用数据类型转换int基本数据类型了。 Character:把char基本类型封装成Character引用数据类型,可以调用方法了。了解几个方法就可以了。 Pattern:正则表达式的编译表示形式。模式对象。 Matcher:匹配器对象。 Math:针对数学运算操作的类。 Random:产生随机数的类。 System:系统类,提供了几个有用方法。 BigInteger:关于大整数的运算的类。 BigDecimal:关于浮点数的运算用这个,不会有精度的丢失。 Date:针对日期操作的类,可以精确到毫秒。 DateFormat:针对日期进行格式化或者针对字符串(文本)进行解析的类。 Calendar:日历类,把所有的日历字段(成员变量)进行了封装,要什么,自己使用获取方法,然后拼接。我的GitHub地址: https://github.com/heizemingjun 我的博客园地址: http://www.cnblogs.com/chenmingjun 我的蚂蚁笔记博客地址: http://blog.leanote.com/chenmingjun Copyright ©2018 黑泽明军 【转载文章务必保留出处和署名,谢谢!】

优秀的个人博客,低调大师

java中多线程的控制

1.需求: 用三个线程按顺序输出A,B,C十次,且不乱序。 2.相关方法: synchronized关键字 synchronized可以锁住代码段不被多个线程同时执行,可以锁住对象,也可以进行全局锁。 参考:http://blog.csdn.net/luoweifu/article/details/46613015 jion() t.join(); //调用join方法,等待线程t执行完毕 t.join(1000); //等待 t 线程,等待时间是1000毫秒 wait(), notify(), notifyAll 1)wait()、notify()和notifyAll()方法是本地方法,并且为final方法,无法被重写。 2)调用某个对象的wait()方法能让当前线程阻塞,并且当前线程必须拥有此对象的monitor(即锁,或者叫管程) 3)调用某个对象的notify()方法能够唤醒一个正在等待这个对象的monitor的线程,如果有多个线程都在等待这个对象的monitor,则只能唤醒其中一个线程; 4)调用notifyAll()方法能够唤醒所有正在等待这个对象的monitor的线程; 看到这个需求,我头脑里第一印象就是使用synchronized 那么接下来的就很简单了 3.实现 public class ThreadControl { public static Count count = new Count(0); public static void main(String arg[]) { MyThread myThreadA = new MyThread(count); MyThread myThreadB = new MyThread(count); MyThread myThreadC = new MyThread(count); myThreadA.start(); myThreadB.start(); myThreadC.start(); } } class Count{ private int count; Count(int count) { this.count = count; } public synchronized int inc() { if(count%3==0) { System.out.print("A"); }else if(count%3==1) { System.out.print("B"); }else if(count%3==2) { System.out.println("C"); } count++; return count; } } class MyThread extends Thread{ private Count count; MyThread(Count count){ this.count = count; } @Override public void run() { super.run(); while (count.inc()<30); } } 我用synchronized给inc()方法上了锁。 运行结果: ABC(1) ABC(2) ABC(3) ABC(4) ABC(5) ABC(6) ABC(7) ABC(8) ABC(9) ABC(10) AB 我只想打印10次ABC,但是最后多出了AB。 当我把myThreadB.start()和myThreadC.start()注释掉后就正常了。 我认为原因是当count=29时,三个线程都在while循环中,而count.inc()又是先执行再获得返回值的, 线程无法及时得知count=30,所以会多打印2次。 这种方法明显需要优化,只需要在打印前加上一个判断即可 public synchronized int inc() { //打印前判断 if(!(count<30)) { return count; } count++; if(count%3==1) { System.out.print("A"); }else if(count%3==2) { System.out.print("B"); }else if(count%3==0) { System.out.println("C("+count/3+")"); } return count; } 其实上面是输出控制,不是线程控制 4.后序相关 我们同样可以用Lock来加锁,实现对线程的控制。 参考下面的网站:http://ifeve.com/locks/ 里面提到一个可重入的问题,不过我个人对于可重入不太理解,大家得自己研究一下了。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册