欢迎来到我的个人网站。交流请加我好友: 919201148。欢迎关注公众号或视频号:蜗牛互联网
Solo  当前访客:2 开始使用

白色蜗牛的互联网心得

我要一步一步往上爬,在最高点乘着叶片往前飞

存档: 2016 年 05 月 (23)

Spring管理的Bean的生命周期

2016-05-28 18:20:12 huayonglun
0  评论    216  浏览

Bean实例化之后的初始化工作 实现接口 org.springframework.beans.factory.InitializingBean 接口指定一个单一的方法: void afterPropertiesSet() throws Exception; 因此,你可以简单地实现上述接口和初始化工作可以在 afterPropertiesSet() 方法中执行,如下所示: public class PersionServiceBean implements InitializingBean { public void afterPropertiesSet() { // do some initialization work } } XML配置 在基于 XML 的配置元数据的情况下,你可以使用 init-method 属性来指定带有 void 无参数方法的名称。例如: <bean id="persionService" class="com.liuyong666.service.impl.PersionServiceBean" init-method="init"....

, ,

Spring装配基本属性的原理

2016-05-31 17:20:12 huayonglun
0  评论    213  浏览

依赖注入对象方式二 使用内部bean,但该bean不能被其他bean使用 <bean id="personService" class="com.liuyong666.service.impl.PersonServiceBean"> <property name="personDao"> <bean class="com.liuyong666.dao.impl.PersonDaoBean"></bean> </property> </bean> 两种方式的优缺点比较 使用ref的方式,引用的bean可以被多个bean引用 而采用内部bean的方式,内部bean只能为那个bean里面那那个属性使用。 前面都是注入依赖对象,那么如何注入基本类型呢? 例如,在PersonServiceBean里面添加一个String类型的name属性和Integer类型的id属性,可以这样注入值: <property name="name" value="huayonglun"></property&g....

, , ,

【Spring 系列】二、spring三种实例化bean的方式

2016-05-27 18:17:12 huayonglun
0  评论    213  浏览

【Spring 系列】二、spring三种实例化bean的方式 beans.xml中配置 <!-- 三种实例化bean的方式 --> <!-- 1.使用类构造器实例化 --> <bean id="personService" class="com.liuyong666.service.impl.PersonServiceBean"></bean> <!-- 2.使用静态工厂方法实例化 --> <bean id="personService2" class="com.liuyong666.service.impl.PersonServiceBeanFactory" factory-method="createPersonServiceBean"></bean> <!-- 3.使用实例工厂方法实例化 --> <bean id="personServiceFactory" class="com.liuyong666.service.impl.PersonServiceBeanFacto....

, ,

Spring如何装配各种集合类型的属性

2016-05-31 18:20:12 huayonglun
0  评论    212  浏览

首先在bean里面声明这些属性,并设置相应的更改器方法和访问器方法 private Set<String> sets = new HashSet<>(); private List<String> lists = new ArrayList<>(); private Properties properties = new Properties(); private Map<String, String> maps = new HashMap<> (); 接着在beans.xml做如下配置 <property name="sets"> <set> <value>set第一个</value> <value>set第二个</value> <value>set第三个</value> </set> </property> <property name="lists"> <set> ....

, , ,

模拟spring自定义上下文获取bean

2016-05-27 18:20:12 huayonglun
0  评论    217  浏览

模拟spring自定义上下文获取bean 利用dom4j解析 设置两个域,一个List存放BeanDefinition,一个Map存放实例化对象的映射 构造器传配置文件进去,依次执行两个方法 方法1,读取配置文件,把解析出的BeanDefinition放入List中 方法2,完成bean的实例化,把实例化对象的映射放入Map中 定义获取bean实例的方法,从Map中根据实例名返回Object对象 import java.net.URL; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.XPath; import org.dom4j.io.SAXReader; /** * 自己的容器 * @author Administrator * */ public class MyClassPathXM....

, ,

Spring依赖注入的原理

2016-05-29 18:20:12 huayonglun
0  评论    213  浏览

使用Spring,可以使用里面的控制反转把依赖对象交给Spring管理,并把依赖对象通过容器注入到组件内部。 那么在Spring里面,该如何把对象注入到组件内部呢? 创建一个PersonDao对象,并把这个对象注入到PersonServiceBean中 依赖注入使用 PersonDaoBean package com.liuyong666.dao.impl; import com.liuyong666.dao.PersonDao; public class PersonDaoBean implements PersonDao{ @Override public void add(){ System.out.println("执行PersonDaoBean里的add()方法"); } } 抽取接口 package com.liuyong666.dao; public interface PersonDao { public abstract void add(); } 说明 接口跟实现类不要放一块,接下来,如何将PersonDaoBean对象注入进PersonServiceBea....

, , ,

配置Spring管理的bean的作用域

2016-05-28 18:20:12 huayonglun
0  评论    211  浏览

配置Spring管理的bean的作用域 .singleton 在每一个spring IoC容器中一个bean定义只有一个对象实例。默认情况下会在容器启动时初始化bean,但我们可以指定bean节点的lazy-init = "true"来延迟初始化bean,这时候,只有第一次获取bean才会初始化bean。如下: <bean id="persionService" class="com.liuyong666.service.impl.PersionServiceBean" lazy-init = "ture"/> 如果想对所有bean都应用延迟初始化,可以在节点beans设置default-lazy-init = “ture” ,如下: <beans default-lazy-init = "ture".../> .prototype 每次从容器获取bean都是新的对象。 在第一次获取bean时初始化 <bean id="persionService" class="com.liuyong666.service.impl.PersionSe....

, ,

【Spring 系列】一、如何从spring中获取bean

2016-05-27 16:20:12 huayonglun
0  评论    209  浏览

【Spring 系列】一、如何从spring中获取bean 导包 spring要管理的类信息 package com.liuyong666.service.impl; ​ import com.liuyong666.service.PersonService; public class PersonServiceBean implements PersonService { @Override public void save(){ System.out.println("我是save()方法"); } } spring面向接口编程,该类对应的接口 public interface PersonService { ​ public abstract void save(); ​ } 配置beans.xml文件,文件在src目录下 <bean id="personService" class="com.liuyong666.service.impl.PersonServiceBean"></bean> 使用spring获取bean @Test ​ ....

, ,

15.原子变量与非阻塞同步机制

2016-05-10 02:26:31 huayonglun
0  评论    216  浏览

java.util.concurrent包中的许多类,比如Semaphore和ConcurrentLinkedQueue,都提供了比使用synchronized更好的性能和可伸缩性。这一章,我们来学习这些性能提升的原始来源:原子变量和非阻塞的同步机制。 近来很多关于并发算法的研究都聚集在非阻塞算法上,这种算法使用低层原子化的机器指令取代锁,比如比较并交换,从而保证数据在并发访问下的一致性。非阻塞算法广泛用于操作系统和JVM中的线程和进程调度、垃圾回收以及实现锁和其他并发数据结构。 与基于锁的方案相比,非阻塞算法的设计和实现都要复杂得多,但是它们在可伸缩性或活跃度上占有很大的优势。因为非阻塞算法可以让多个线程在竞争相同资源时不会发生阻塞,所以它能在更精化的层面上调整粒度,并能大大减少调度的开销。 进一步而言,它们对死锁和其他活跃度问题具有免疫性。在基于锁的算法中,如果一个线程在持有锁的时候休眠,或者停滞不前,那么其他线程就都不可能前进了,而非阻塞算法不会受到单个线程失败的影响。 在java 5.0 中,使用原子变量类,比如AtomicInteger和AtomicReference,能够高....

, ,

14.构建自定义的同步工具

2016-05-09 02:26:31 huayonglun
0  评论    216  浏览

类库中包含了大量依赖于状态(state-dependent)的类——这些类拥有基于状态的先验条件——FutureTask、Semaphore和BlockingQueue。例如,你不能从一个空队列中移除条目,也不能从一个尚未结束的任务中获取结果;在这些操作可以执行前,你必须等到队列进入“非空”状态,任务进入“完成”状态。 创建状态依赖类最简单的方法通常是将它构建于已有的状态依赖库之上。如果类库没有提供你需要的功能,你也可以使用语言和类库提供的底层机制,包括内部条件队列、显示的Condition对象和AbstractQueuedSynchronizer框架,构建属于自己的Synchronizer。这一章探究一些实现状态依赖性时要面对的不同选择,以及使用平台提供的状态依赖性机制时需要遵守的不同规则。 14.1 管理状态依赖性 生产者-消费者的设计经常会使用ArrayBlockingQueue这种有限缓存。一个有限缓存提供的put和take操作,每一个都有先验条件:你不能从空缓存中获取元素,也不能把元素置入已满的缓存中。如果依赖于状态的操作在处理先验条件时失败,可以抛出异常或者返回错误状态....

, ,

13.显式锁

2016-05-08 02:26:31 huayonglun
0  评论    214  浏览

在Java 5.0之前,用于调节共享对象访问的机制只有synchronized和volatile Java 5.0 提供了新的选择:ReentrantLock。 ReentrantLock并不是作为内部锁的替代,而是当内部锁被证明受到局限时,提供可选择的高级特性。 13.1 Lock 和 ReentrantLock Lock接口,定义了一些抽象的锁操作 与内部加锁机制不同,Lock提供了 无条件 可轮询 定时 可中断的锁获取操作 所有加锁和解锁的方法都是显式的。 public interface Lock { void lock(); void lockInterruptibly() throws InterruptedException; boolean tryLock(long time, TimeUnit unit) throws InterruptedException; void unlock(); Condition newCondition(); } ReentrantLock实现了Lock接口,提供了与synchronized相同的互斥和内存可见....

, ,

11.性能和可伸缩性

2016-05-06 02:26:31 huayonglun
0  评论    235  浏览

使用线程最主要的原因是提高性能。使用线程可以使程序更加充分的发挥出闲置的处理能力,从而更好的利用资源;并能够使程序在现有任务正在运行的情况下立刻开始着手处理新的任务,从而提高系统的响应性。 11.1 性能的思考 改进性能意味着用更少的资源做更多的事情。 资源包括CPU周期、内存、网络带宽、I/O带宽、数据库请求、磁盘空间、以及其他一些资源。 当活动的运行因某个特定资源受阻时,我们称之为受限于该资源:受限于CPU,受限于数据库。 虽然目标是提高性能,但是使用多线程总会引入一些性能开销:与协调线程相关的开销(加锁、信号、内存同步),增加的上下文切换,线程的创建和消亡,以及调度的开销。当线程被过度使用后,这些开销会超过吞吐量响应性和计算能力带来的补偿。 另一方面一个没有经过良好并发设计的应用程序,甚至比相同功能的顺序的程序性能更差。 为了实现更好的性能,我们需要更有效的利用现有的处理资源,使CPU尽可能处于忙碌状态。 11.1.1 性能“遭遇”可伸缩性 应用程序可以从很多个角度来衡量: 服务时间、等待时间、(衡量有多快) 吞吐量、生产量、可伸缩性、(衡量有多少) 效率、 可....

, ,

08.应用线程池

2016-05-02 22:23:53 huayonglun
0  评论    211  浏览

本章关注在配置和调整线程池时用的高级选项,讲述了使用任务执行框架的过程中需要注意的危险,还提供了一些使用Executor更高级的例子。 8.1 任务与执行策略间的隐性耦合 前面我们声称Executor框架可以将任务的提交与执行策略解耦,其实有点言过其实了。尽管Executor框架为制定和修改执行策略提供了相当大的灵活性,但是并非所有的任务都能适合所有的执行策略。有些类型的任务需要明确地指定一个执行策略,包括: 依赖性任务。多数运行良好的任务是独立的:它们不依赖于时序,或者其他任务的结果与边界效应。当线程池中运行的任务都是独立的时候,你就可以随意地改变池的长度和配置,这样做不会影响到性能以外的任何事情。另一方面,如果你提交给线程池的任务要依赖于其他的任务,你就隐式地给执行策略带来了约束,这样你必须仔细地管理执行策略以避免活跃度的问题。 采用线程限制的任务。单线程化的Executor相比于任意的线程池,可以对同步作出更强的承诺。它可以保证任务不会并发地执行,允许你放宽任务代码对线程安全的要求。可以把对象限制带任务线程中,这使得任务线程所执行的任务在访问该对象时,不需要同步,即使那些....

, ,

09.GUI应用程序

2016-05-03 18:40:37 huayonglun
0  评论    215  浏览

几乎所有的GUI工具集都实现为单线程化子系统(single-threaded),意味着所有GUI的活动都被限制在一个单独的线程中,这其中就包括了Swing和SWT。 9.1 为什么GUI是单线程化的 早期的GUI应用程序就是单线程化的,GUI在“主事件循环”进行处理。现代的GUI框架使用了一个略微不同的模型:模型创建了一个专门的线程,**事件派发线程(event dispatch thread,EDT)**来处理GUI事件。 9.1.1 顺序事件处理 任务依次处理,不会交迭 不利的一面:如果一个任务处理时间长,其他任务必须等。 9.1.2 Swing中的线程限制 所有的Swing组件(比如JButton和JTable)和数据模型(TableModel和TreeModel)都被限制于事件线程中,所以任何访问它们的代码必须在事件线程中运行。GUI对象不用同步,仅仅依靠线程限制来保持一致性。 Swing的单线程规则:Swing的组件和模型只能在事件分派线程中被创建、修改和请求。 //使用Executor实现的SwingUtillities public class Swi....

, ,

10.避免活跃度危险

2016-05-04 20:00:00 huayonglun
0  评论    214  浏览

安全性和活跃度通常相互牵制。我们使用锁来保证线程安全,但是滥用锁可能引起锁顺序死锁(lock-ordering deadlock)。 我们使用线程池和信号量来约束资源的使用,但是却不能知晓那些管辖范围内的活动可能形成的资源死锁(resource deadlock)。 这一章将讲述一些引发活跃度失败的原因,以及避免发生这些失败的方法。 10.1 死锁 经典的“哲学家进餐问题”很好的解释了死锁。 当一个线程永远占有一个锁,而其他线程尝试去获得这个锁,那么它们将永远被阻塞。当线程A占有锁L时,想要获得锁M,但是同时,线程B持有M,并尝试获得L,两个线程将永远等待下去。这种情况是死锁最简单的形式(或称致命的拥抱,deadly embrace),发生在多个线程因为环路的锁依赖关系而永远等待的情况下。(把这些线程假想为有向图的节点,图的边表现了这个关系:线程A等待线程B占有的资源,如果图最后连成了一个环路,那么死锁也就产生了。) 数据库系统的设计就针对了监测死锁,以及从死锁中恢复。一个事务可能需要取得许多锁,并可能一直持有这些锁,直到所有事务提交。如此说来两个事务非常有可能发生死锁,但这却并不....

, ,

16.Java存储模型

2016-05-11 02:26:31 huayonglun
0  评论    216  浏览

高层的设计问题,比如安全发布、规约、以及遵守同步策略等等。它们的安全性得益于JMM,当你理解了这些机制会如此工作后,能发现可以更容易有效地使用它们。 16.1 什么是存储模型,要它何用 假设一个线程为变量a赋值:a = 3; 存储模型要回答这个问题:“在什么条件下,读取a的线程会看到3这个值?” 编译器生成指令的次序,可以不同于源代码所暗示的“显然”的版本,而且编译器还会把变量存储在寄存器,而不是内存中;处理器可以乱序或者并行地执行指令;缓存会改变写入提交到主内存的变量的次序;最后,存储在处理器本地缓存中的值,对于其他处理器并不可见。这些因素都会妨碍一个线程看到一个变量的最新值,而且会引起内存活动在不同的线程中表现出不同的发生次序——如果你没有适当同步的话。 Java语言规范规定了JVM要维护内部线程类似顺序化语意:只要程序的最终结果等同于它在严格的顺序化环境中执行的结果,那么上述所有行为是允许的。 最近几年,重新排序后的指令使得程序在计算性能上得到了很大的提升。对性能提升作出贡献的,除了越来越高的时钟频率,还有不断提升的并行性——管道超标量体系结构执行单元,动态指令调度,试探性执....

, ,

07.取消和关闭

2016-05-01 23:16:49 huayonglun
0  评论    210  浏览

启动任务和线程都很容易。大多数时候,我们通常允许它们在结束任务后自行停止。但是,有时候我们希望任务或线程自然结束之前就停止它们,可能因为用户取消了操作,或者应用程序需要快速关闭。 要做到安全、快速、可靠的停止任务或线程并不容易。Java没有提供任何机制,来安全地强迫线程停止手头的工作。它提供中断——一个协作机制,使一个线程能够要求另一个线程停止当前的工作。 这种协作方法是必须的,因为我们很少需要一个任务、线程或者服务立即停止,立即停止会导致共享的数据结构处于不一致的状态。任务和服务可以这样编码:当要求它们停止时,它们首先会清除当前进程中的工作,然后再终止。这提供了更好的灵活性,因为任务代码本身比发出取消请求的代码更明确应该清除什么。 7.1 任务取消 当外部代码能够在活动自然完成之前,把它更改为完成状态,那么这个活动被称为可取消的(cancellable)。我们可能会因为很多原因取消一个活动: 用户请求的取消。用户点击程序界面上的“cancel”按钮,或者通过管理接口请求取消,比如JMX(Java Management Extensions)。 **限时活动。**一个应用程序,需....

, ,

12.测试并发程序

2016-05-07 02:26:31 huayonglun
0  评论    207  浏览

并发类的测试基本分为两类: 安全性测试:什么坏事都没有发生过 活跃性测试:好的事情终究会发生 与活跃度测试相关的是性能测试。性能可以通过很多方式来测量,其中包括: 吞吐量:在一个并发任务集里,已完成任务所占的比例; 响应性:从请求到完成一些动作之间的延迟(也被称作等待时间); 可伸缩性:增加更多的资源(通常是指CPU),就能提高(或者缓解短缺)吞吐量。 12.1 测试正确性 SemaphoreBoundedBuffer实现一个基于数组的定长队列 put和take方法可阻塞并受控于一对计数信号量 availableItems代表可以从缓存中删除的元素的个数,初始值为0 availableSpaces代表可以插入到缓存的元素的个数,初始值为缓存的大小 take操作首先请求一个许可(permit),这个许可从availableItems中获得。 如果缓存不为空,请求立即成功,否则请求会被阻塞,直到缓存不空为止。 一旦获得了许可,take会删除缓存中的下一个元素,同时还释放一个许可给availableSpaces信号量。 //利用Semaphore实现的有限缓存 @Th....

,

struts2中自定义类型转换器之局部类型转换器

2016-05-28 02:50:27 huayonglun
0  评论    219  浏览

Struts2自定义类型转换器 应用中,常需要将字符串请求参数转换为相应的数据类型,或将一定的数据类型类型转换为字符串显示显示给用户,Struts2提供了类型转换机制。 Struts2的类型转换是基于OGNL表达式的,只要我们把HTML输入项(表单元素和其他GET/POET的参数)命名为合法的OGNL表达式,就可以充分利用Struts2的转换机制。 除此之外,Struts2提供了很好的扩展性,可以实现自己的类型转换器,完成字符串和自定义复合类型之间的转换。总之,Struts2的类型转换器提供了非常强大的表现层数据处理机制,可以利用Struts2的类型转换机制来完成任意的类型转换。 Struts2自定义类型转换器分为局部类型转换器和全局类型转换器。 局部类型转换器:对某个action起作用 全局类型转换器:对所有的action起作用 局部类型转换器 如果页面传来一个参数xxx.action?birthday=20160527到后台action,然后action属性用Date类型进行接收,用Date类型是获取不到,并且会出现错误的,struts2提供了一种类型转换器供我们使用。....

, ,

struts2中请求参数接收

2016-05-27 02:50:27 huayonglun
0  评论    218  浏览

采用基本类型接受请求参数(get/post) 在Action类中定义与请求参数同名的属性,struts2便能自动接收请求参数并赋予给同名的属性。 请求路径:http://localhost:8080/action/xxx.action?id=66 public class HelloWorldAction { private Integer id; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } } 采用复合类型接受请求参数 获取Bean属性的原理: Struts2首先通过反射技术调用Person的默认构造器创建person的实例,然后再通过反射技术调用person中与请求参数同名的属性的setter方法,来获取请求参数数值。 请求路径:http://localhost:8080/action/xxx.action?person.id=1&person.name=zhangsan 实体bean public class Person { p....

, ,
TOP