黑马程序员——高新技术—AOP面向方面编程

来源:互联网 发布:下载在线音乐的软件 编辑:程序博客网 时间:2024/05/29 12:00

------<ahref="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

空中网面试题

       本题要求键相同的两个对象间隔1秒进行输出,键不同的对象同时输出,另外即使键在字面上相同,即用equals进行内容比较一致,但由于每个键与空字符串进行相连,形

成了新的字符串,故即使是字符串常量,但也是两个不同的对象。

       故第一步是能不能想到用键作为同步锁,第二步是用线程同步的集合进行键值的存储,第三步是当集合中存在equals相等的键时,要获取同一把锁。

       另外一点值得注意的是ArrayList在进行迭代操作时,不能引用集合对象来操作集合中的元素,如在迭代时进行元素的增删。这是因为通过参看源代码,迭代器的hasNext方

法在返回值前会比较spectedCount与subCount的值(是在调用迭代器之前由集合增删方法所累加起来的值先赋给subCount,再赋给spectedCount,若在迭代器中再调用集合

中的增删方法,则累加的只有subCount,当两值不等时,hasNext方法会抛出异常)。

package cn.itcast;import java.util.ArrayList;import java.util.Collection;import java.util.Iterator;import java.util.concurrent.CopyOnWriteArrayList;public class CollectionElementsAsLock extends Thread{private String key=null;private String value=null;private PrintKeyValue instance=null;public CollectionElementsAsLock(String key,String key2,String value) {// TODO Auto-generated constructor stubinstance=PrintKeyValue.getInstance();this.key=key+key2;this.value=value;}public static void main(String[] args) {// TODO Auto-generated method stubSystem.out.println("begin:"+System.currentTimeMillis()/1000);new CollectionElementsAsLock("1", "", "张三").start();new CollectionElementsAsLock("1", "", "李四").start();new CollectionElementsAsLock("2", "", "王五").start();new CollectionElementsAsLock("3", "", "赵六").start();}@Overridepublic void run() {// TODO Auto-generated method stubinstance.print(key, value);}}class PrintKeyValue{private PrintKeyValue(){};private static PrintKeyValue instance=new PrintKeyValue();public static PrintKeyValue getInstance(){return instance;}//private Collection<String> keys=new ArrayList<String>();private CopyOnWriteArrayList<String> keys=new CopyOnWriteArrayList<String>();public void print(String key,String value){String realKey=key;if(!keys.contains(key)){keys.add(key);}else{for(Iterator<String> it=keys.iterator();it.hasNext();){try {Thread.sleep(20);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}String tmp=it.next();if(tmp.equals(realKey)){realKey=tmp;}}}synchronized (realKey) {try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(key+":"+value+":"+System.currentTimeMillis()/1000);}}}

AOP面向方面编程

        AOP,面向方面编程,即为各个API类设置代理,在代理类中往往设置一个target(目标字段,即API类)和advice(Advice接口,用于功能扩展)两个字段,目标类可为一

般API类,通过实现Advice接口为API类附加其他功能,以代理对象进行返回。代理对象除了具有原API对象的方法之外,还附加了Advice实现类中的部分或全部功能,如性能测

试等。

       代理的出现,可以按需要进行功能扩展,产生大量具备原目标对象功能的加强代理对象。

       本例实现一个Bean工厂,可通过更改配置文件参数产生普通Bean对象和代理对象:

       首先定义规则:


package cn.itcast;public interface Advice {void beforeMethod();void afterMethod();}

       通过实现规则扩展功能:


package cn.itcast;public class MyAdvice implements Advice {long startTime=0;@Overridepublic void beforeMethod() {// TODO Auto-generated method stubstartTime=System.currentTimeMillis();}@Overridepublic void afterMethod() {// TODO Auto-generated method stublong endTime=System.currentTimeMillis();System.out.println(endTime-startTime);}}

       定义好了扩展功能后,就可以设置代理类:


package cn.itcast;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;public class ProxyFactoryBean {private Object target;private Advice advice;public Object getTarget() {return target;}public void setTarget(Object target) {this.target = target;}public Advice getAdvice() {return advice;}public void setAdvice(Advice advice) {this.advice = advice;}public Object getProxy(){return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args)throws Throwable {// TODO Auto-generated method stubadvice.beforeMethod();Object retVal=method.invoke(target, args);advice.afterMethod();return retVal;}});}}


       Bean工厂:通过InputStream读取配置文件产生普通Bean或代理对象:


package cn.itcast;import java.io.IOException;import java.io.InputStream;import java.util.Properties;public class BeanFactory {private InputStream ips;private Properties props=null;public BeanFactory(InputStream ips) {super();this.ips = ips;props=new Properties();try {props.load(ips);} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public Object getBean(String key){Object obj=null;try {obj=Class.forName(props.getProperty(key)).newInstance();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}if(obj instanceof ProxyFactoryBean){ProxyFactoryBean pfb=(ProxyFactoryBean)obj;Object retVal=null;try {pfb.setAdvice((Advice)Class.forName(props.getProperty(key+".advice")).newInstance());pfb.setTarget(Class.forName(props.getProperty(key+".target")).newInstance());retVal=pfb.getProxy();} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}return retVal;}return obj;}}


       config.properties  配置文件如下:


#***=java.util.ArrayList***=cn.itcast.ProxyFactoryBean***.target=java.util.HashSet***.advice=cn.itcast.MyAdvice


   主函数进行测试:


package cn.itcast;import java.util.Collection;public class AOPFrameworkTest {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubBeanFactory beanFactory=new BeanFactory(AOPFrameworkTest.class.getResourceAsStream("config.properties"));Object bean=beanFactory.getBean("***");System.out.println(bean.getClass().getName());Collection collction=(Collection)bean;collction.add("a");collction.add("b");collction.add("c");collction.add("b");System.out.println(collction.size());}}




















0 0