黑马程序员---高新技术

----------------------ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------

1.享元模式

    在自动拆箱和装箱中(JDK1.5引入),针对Integer类型对象所存储的值的大小,对象表现出不同状态。
    Demo:

public class Demo {
    public static void main(String[] args) {
        Integer i1 = 3;        //自动装箱 相当于Integer i1 = new Integer(3);
        Integer i2 = 3;
        System.out.println(i1 == i2);
        Integer i3 = 183;
        Integer i4 = 183;
        System.out.println(i3 == i4);
        Integer i5 = Integer.valueOf(6);    //将6打包成一个Integer对象
        Integer i6 = Integer.valueOf(6);
        System.out.println(i5 == i6);
        Integer i7 = Integer.valueOf(186);
        Integer i8 = Integer.valueOf(186);
        System.out.println(i7 == i8);
    }
}
    注:结果为true false true false,一个系统中如果有多个相同的对象,那么只共享一份就可以了,不必每个都去实例化一个对象。对于Integer对象,当值在-128~127之间时,只会装箱成同一个对象,当值超过此范围就会在内存中创建新的对象。


2.单例设计模式中懒汉式线程安全问题

    a.单例
        Demo:

public class ThreadDemo {      
    public static void main(String[] args) {  
        SingleDemo s1 = SingleDemo.getInstance();  
        SingleDemo s2 = SingleDemo.getInstance();  
        System.out.println(s2 == s2);  
    }  
}
class SingleDemo {  
    private static SingleDemo s = null;  
    private SingleDemo(){}  
    public static  SingleDemo getInstance(){  
        if(s == null){  
            s = new SingleDemo();  
        }  
        return s;  
    }  
}
        注:运行结果一直都是true,说明单线程下是没问题的,下面写个多线程来访问单例
        Demo:

public class ThreadDemo implements Runnable {    
    Set<Single> singles = new HashSet<Single>();
    public void run() {
        Single s = Single.getInstance();  
        singles.add(s);
    }    
    public static void main(String[] args) {
        ThreadDemo t = new ThreadDemo();  
        for(int i=0; i<10; i++){
            new Thread(t).start();  
            System.out.println(t.singles);  
        }
        
    }
}
class Single {  
    private static Single s = null;  
    private Single(){}  
    public static  Single getInstance(){  
        if(s == null){  
            s = new Single();  
        }  
        return s;  
    }  
} 
         运行结果如下:
        [com.hanxuhui.blog.high_tech.Single@12452e8],[com.hanxuhui.blog.high_tech.Single@11671b2, com.hanxuhui.blog.high_tech.Single@bc8e1e]或
        [com.hanxuhui.blog.high_tech.Single@11671b2]
        说明有线程并发访问安全问题,获取的不一定都是同一个实例
      如何解决线程安全问题呢?当然使用同步锁机制了啊


    b.改进单例:
class Single {  
    private static Single s = null;  
    private Single(){}  
    public static synchronized Single getInstance(){  
        if(s == null){  
            s = new Single();  
        }  
        return s;  
    }  
} 
    加入同步函数后线程安全问题解决了,运行多次都是获取同一个实例,不会出现2个实例的情况了
    [com.hanxuhui.blog.high_tech.Single@11671b2]
     但是在多线程并发访问的情况下,每个线程每次获取实例都要判断下锁,效率比较低,为了提高效率,我加入了双重判断的方法,解决了效率的问题
    代码如下:

class Single {  
    private static Single s = null;  
    private Single(){}  
    public static  Single getInstance(){  
        /*如果第一个线程获取到了单例的实例对象,后面的线程再获取实例的时候不需要进入同步代码块中了*/  
        if(s == null){  
            //同步代码块用的锁是单例的字节码文件对象,且只能用这个锁  
            synchronized(Single.class){  
                if(s == null){  
                    s = new Single();  
                }  
            }  
        }  
        return s;  
    }  
} 
    注:用这种方式解决了懒汉式的线程安全问题,也提高了效率,但是在实际开发中还是用饿汉式的比较多,毕竟这个代码比较多,比较繁琐。


3.枚举

    枚举中的每个元素都是枚举对象,枚举有默认的构造方法,当第一次使用枚举时,就会调用构造方法对每个枚举对象进行初始化。
    Demo:

public class EnumerationDemo {
    public static void main(String[] args) {
        Weekday weekday = Weekday.SUN;
        System.out.println(weekday.name());
        System.out.println(weekday.ordinal());
        System.out.println(weekday.getClass());
        System.out.println(weekday.hashCode());
        System.out.println(weekday.valueOf("MON"));
        System.out.println(weekday.values().length);
    }
}
enum Weekday{
    SUN,MON,TUE,WED,THI,FRI,SAT;
    private Weekday(){
        System.out.println("first");
    }
    private Weekday(int i){
        System.out.println("second");
    }    
}
    交通灯枚举创建:
public enum TrafficLamp{
    RED(30){
        public TrafficLamp nextLamp(){        //new实例时,使用匿名内部类,实现子类的抽象方法
            return YELLOW;
        }
    },
    GREEN(45){
        public TrafficLamp nextLamp(){
            return YELLOW;
        }
    },
    YELLOW(5){
        public TrafficLamp nextLamp(){
            return GREEN;
        }
    };
    public abstract TrafficLamp nextLamp();        //抽象方法
    private int time;
    private TrafficLamp(int time){                //带参构造方法
        this.time = time;
    }
}


4.反射

    反射就是把java类中的各种成分映射成相应的java类。
    a.取得相应类的字节码的三种方式(以String为例)

public class ReflectDemo {
    public static void main(String[] args) throws Exception {
        String str = "han";
        Class cls1 = String.class;
        Class cls2 = str.getClass();
        Class cls3 = Class.forName("java.lang.String");
        System.out.println(cls1 == cls2);//true
        System.out.println(cls1 == cls3);//true
    }
}
         注:八中基本类型(byte,short,char,int,long,float,double,boolean)和void都有自己的字节码。每种类型的字节码在jvm中只存在一份。
    b.构造器反射
        使用Class的构造器,可以实现不同类型数据对象的构建。

        //new String(new StringBuffer("abc"));
        Constructor constructor = String.class.getConstructor(StringBuffer.class);//得到String的构造器,参数为StringBuffer类型
        String str2 = (String)constructor.newInstance(new StringBuffer("abc"));//调用构造的newInstance()方法,并传入StringBuffer类型数据,构造出String对象。
        System.out.println(str2.charAt(2));//打印字符串第三个字符

     c.成员变量的反射
        1)新建类ReflectPointDemo

public class ReflectPointDemo {    
    private int x;
    public int y;
    public ReflectPointDemo(int x, int y) {
        super();
        this.x = x;
        this.y = y;
    }
}
         2)在测试类中测试
            ReflectPointDemo rpd = new ReflectPointDemo(5, 6);
            //fieldY不是对象身上的变量,而是类上的,要使用它,就必须制定要取的是哪个对象上的y值
            Field fieldY = rpd.getClass().getField("y");
            //x为私有成员变量,使用getField("x")不能看到变量x,但是使用getDeclaredField("x")就可以看见私有的变量
            Field fieldX = rpd.getClass().getDeclaredField("x");
            fieldX.setAccessible(true);//暴力反射,强制使私有成员变量可用
            System.out.println(fieldY.get(rpd));
            System.out.println(fieldX.get(rpd));
        3)遍历类中成员变量,改变String类型的变量的值。

private static void replaceStringValue(ReflectPointDemo rpd) throws Exception {
    Field[] fields = rpd.getClass().getFields();
    for(Field field : fields){
        if(field.getType() == String.class){
            String oldVal = (String)field.get(rpd);
            String newVal = oldVal.replace('b', 'a');
            field.set(rpd, newVal);
        }
    }
}
    d.成员方法的反射
        //str1.charAt(1);
        Method charAt = String.class.getMethod("charAt", int.class);//拿到String的charAt方法
        System.out.println(charAt.invoke(str1, 3));//相当于str1.charAt(3);
        对接收数组参数的反射
        1)新添内部类ArgumentTest

class ArgumentTest{
    public static void main(String[] args) {
        for(String str : args){
            System.out.println(str);
        }
    }
}
        2)在主方法中添加以下语句,运行程序传入参数
            String startClassName = args[0];//将字符串com.hanxuhui.blog.high_tech.ArgumentTest传入main方法参数
            Method mainMethod = Class.forName(startClassName).getMethod("main", String[].class);//拿到主方法
            mainMethod.invoke(null, (Object)new String[]{"aaa","bbb","ccc"});//调用main方法,静态方法对象置为null
    e.数组的反射
        1)定义新方法printObject

private static void printObject(Object obj) {
    Class c = obj.getClass();
    if(c.isArray()){
        for(int i=0; i<Array.getLength(obj); i++){
            System.out.println(Array.get(obj, i));
        }
    }else{
        System.out.println(obj);
    }
}
        2)在主方法中定义变量并调用方法
            String[] strs = new String[]{"a","b","c"};
            Object obj = strs;
            printObject(obj);
    f.配置文件的读取和反射
        1)在项目下新建配置文件config.properties,里面写上className=java.util.ArrayList
        2)新建java类PropertiesDemo

public class PropertiesDemo {
    public static void main(String[] args) throws Exception {
        InputStream in = new FileInputStream("config.properties");//new字节流对象
        Properties p = new Properties();
        p.load(in);//加载数据
        in.close();
        String className = p.getProperty("className");//取出文件中的字符串值
        
        Collection c = (Collection)Class.forName(className).newInstance();//利用反射取得字符串所对应类对象
        //Collection c = new HashSet();
        ReflectPointDemo rpd1 = new ReflectPointDemo(3, 3);
        ReflectPointDemo rpd2 = new ReflectPointDemo(5, 5);
        ReflectPointDemo rpd3 = new ReflectPointDemo(6, 6);
        c.add(rpd1);
        c.add(rpd2);
        c.add(rpd3);
        c.add(rpd1);
        System.out.println(c.size());
    }
}
5.javabean
    a.对javabean的简单内省操作
        1)新建person类,为其添加x,y两个成员变量,完成get,set和带参构造方法的书写
        2)书写测试类IntroSpectorDemo

public class IntroSpectorDemo {
    public static void main(String[] args) throws Exception {
        PersonDemo p = new PersonDemo(5,6);
        String propertyName = "x";
        PropertyDescriptor pd = new PropertyDescriptor(propertyName, PersonDemo.class);
        Method methodGetX = pd.getReadMethod();
        Object obj = methodGetX.invoke(p);
        System.out.println(obj);
        
        Method methodSetX = pd.getWriteMethod();
        methodSetX.invoke(p,12);
        System.out.println(p.getX());
    }
}

6.泛型集合综合
    Demo:

public class GenericDemo {
    public static void main(String[] args) {
        Map<String,Integer> maps = new HashMap<String,Integer>();//指定Map中存放的元素类型
        maps.put("a", 1);
        maps.put("b", 2);
        maps.put("c", 3);
        Set<Map.Entry<String,Integer>> sets = maps.entrySet();//通过Map的entrySet()方法取得集合中的键值对
        for(Map.Entry<String, Integer> entry : sets){
            System.out.println(entry.getKey() + "," + entry.getValue());//循环遍历输出集合中元素
        }
    }
}

7.类加载器
    a.Java虚拟机中可以安装多个类加载器,系统默认三个主要类加载,每个类负责加载特定位置的类 BootStrap,ExtClassLoader,AppClassLoader
        BootStrap:加载JDK下的rt.jar;
        ExtClassLoader:加载的是jre下lib/ext里的jar包;
        AppClassLoader:加载的是ClassPath路径下的文件。
        
    b.类加载器也是Java类,因此类加载器本身也要被类加载器加载,显然必须有第一个类加载器不是Java类,这正是BootStrap类,它是C++写的。Java虚拟机中的所有类加载器采用具有父子关系的树形结构进行组织,在实例化每个类加载器对象时,需要为其制定一个父级类加载器对象或者默认采用系统类加载器为其父类加载器。      
    c.类加载器的委托机制:先让父类类加载器加载文件,找不到文件在自己找;当所有祖宗类加载器没有加载到类,回到发起者类加载器,还加载不了,则抛ClassNotFoundException,不是再去找发起者类加载器的儿子,因为没有getChild()方法,即使有,那有多个儿子,找哪一个呢?
        Java虚拟机加载一个类时:
            1、首先当前线程的类加载器去加载线程中的第一个类;
            2、如果类A中引用了类B,Java虚拟机将使用加载器A的类加载器来加载类B。
            3、还可以直接调用ClassLoader loadClass()方法来制定某个类加载器去加载某个类。    
    d.编译一个类加载器:继承ClassLoader类,实现findClass()方法
        Demo:

public class MyClassLoader extends ClassLoader{  
    public static void main(String[] args){  
        String srcPath = args[0];  
        String destDir = args[1];  
        FileInputStream fis = new FileInputStream(srcPath);  
        String destFileName = srcPath.substring(srcPath.lastIndexOf('\\')+1);  
        String destPath = destSrc + "\\" + destFileName;  
        FileOutputStream fos = new FileOutputStream(destPath);  
        cypher(fis,fos);  
        fis.close();  
        fos.close();  
    }  
    //加密,解密程序  
    private static void cypher(InputStream is,OutputStream os)throws Exeption{  
        int b = -1;  
        while((b=is.read())!=-1){  
            os.write(b ^ 0xff);  
        }  
    }  
    private String classDir;   
    protected Class<?> findClass(String name) throws ClassNotFoudException{  
        String classFileName = classDir + "\\"+name+".class";  
        try{  
            FileInputStream fis = new FileInputStream(classFileName);  
            ByteArrayOutputStream bos = new ByteArrayOutputStream();  
            cypher(fis,bos);  
            fis.close();  
            byte[] bytes = bos.toByteArray();  
            return defineClass(bytes,0,bytes.length);  
        }catch(Exception x){}                        
        return super.findClass(name);  
    }  
              
    public MyClassLoader(){}  
    public MyClassLoader(String classDir){  
        this.classDir = classDir;  
    }  
} 
 
    e.自定义类加载器,并对类实现加密解密:
        1)新建类ClassDemo

public class ClassDemo {
    public String toString() {  
        return "hanxuhui";  
    }  
}
        2)自定义类加载器加载ClassDemo类的ClassDemo.class文件
public class ClassLoaderDemo extends ClassLoader{
    public static void main(String[] args)throws Exception{
        Class clazz = new ClassLoaderDemo().loadClass("ClassDemo.class");
        System.out.println(clazz.getName());
        Object obj = (Object)clazz.newInstance();
        System.out.println(obj);
    }
    protected Class<?> findClass(String name)throws ClassNotFoundException{
        try{
            FileInputStream fis = new FileInputStream(name);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            Change.lock(fis,baos);
            fis.close();
            byte[] bytes = baos.toByteArray();
            return defineClass(null,bytes,0,bytes.length);
        }catch(Exception e){
            System.out.println(e);
        }
        return null;                        
    }
}

class Change{
    public static void main(String[] args)throws Exception{
        FileInputStream fis = new FileInputStream(args[0]);
        FileOutputStream fos = new FileOutputStream(args[1]);
        lock(fis,fos);
    }
    public static void lock(InputStream is,OutputStream os)throws Exception{
        int b = -1;
        while((b=is.read())!=-1){
            os.write(b ^ 0xff);
        }
        is.close();
        os.close();
    }
}

8.代理
    a.代理就是在原有类的基础上增加一些系统功能。
    b.AOP意思是面向切面的编程。
    c.动态代理技术:
        JVM可以在运行期动态生成出类的字节码,这种动态的类往往被用作代理类,即动态代理类。
        JVM生成的动态类必须实现一个或多个接口,所以JVM生成的动态类只能用作具有相同接口的目标类的代理。
        CGLIB库可以动态生成一个类的子类,一个类的子类也可以用作该类的代理,所以,如果要为一个没有实现接口的类生成动态代理类,那么可以使用CGLIB库。
        代理类的各个方法中通常除了要调用目标的相应方法和对外返回目标返回的结果外,还可以在代理方法的如下四个位置加上系统功能代码:
            1、调用目标方法前
            2、调用目标方法后
            3、调用目标方法前后
            4、在处理目标方法异常的catch块中。
        Demo:

public class ProxyTest {
    public static void main(String[] args) throws Exception {
        Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
        //对于class,我们通常认为它是字节码
        System.out.println(clazzProxy1.getName());
        System.out.println("begin constructors list-----:");
        Constructor[] constructors = clazzProxy1.getConstructors();        //得到它的构造方法
        for (Constructor constructor : constructors) {
            String name = constructor.getName();
            StringBuilder sBuilder = new StringBuilder();        //用StringBuilder效率更高一点
            sBuilder.append('(');

            Class[] clazzParams = constructor.getParameterTypes();        //得到参数的类型,返回的是一个class的数组。
            for (Class clazzParam : clazzParams) {        //取出每个参数的名字
                sBuilder.append(clazzParam.getName()).append(',');
            }
            if (clazzParams != null && clazzParams.length != 0)
                sBuilder.deleteCharAt(sBuilder.length() - 1);        //去掉最后一个参数
            sBuilder.append(')');
            System.out.println(sBuilder.toString());
        }
        //StringBuilder与StringBuffered的区别:
        //在动态上,都是往字符串中添加字符,在单线程下,用StringBuilder效率要高一点,在多线程下StringBufferd要高点
        System.out.println("----------begin methods list----------");
        Method[] methods = clazzProxy1.getMethods();
        for (Method method : methods) {
            String name = method.getName();
            StringBuilder sBuilder = new StringBuilder(name);
            sBuilder.append('(');
            Class[] clazzParams = method.getParameterTypes();
            for (Class clazzParam : clazzParams) {
                sBuilder.append(clazzParam.getName()).append(',');
            }
            if (clazzParams != null && clazzParams.length != 0)
                sBuilder.deleteCharAt(sBuilder.length() - 1);
            sBuilder.append(')');
            System.out.println(sBuilder.toString());
        }
        // 创建动态类的实例对象用调用方法
        System.out.println("-----begin create instance-----");
        // Object obj=clazzProxy1.newInstance();//不能这能调用构造参数的实例化方法。
        // 构造方法接受一个参数,然后再去调用构造方法。
        Constructor constructor = clazzProxy1.getConstructor(InvocationHandler.class);
        class MyInvocationHander1 implements InvocationHandler {
            public Object invoke(Object proxy, Method method, Object[] args)
                    throws Throwable {
                return null;
            }
        }
        Collection proxy1 = (Collection) constructor.newInstance(new MyInvocationHander1());
        System.out.println(proxy1);
        proxy1.clear();// 如果不报空指针异常,就说明这个对象是有的。
        // proxy1.size();//出错了,那么就判定size方法出问题了,因为size方法有返回值,clear方法没有。
        Collection proxy2 = (Collection) constructor
                .newInstance(new InvocationHandler() {
                    public Object invoke(Object proxy, Method method,Object[] args) throws Throwable {
                        return null;
                    }
                });
        // 代理对象
        Collection proxy3 = (Collection) Proxy.newProxyInstance(
                Collection.class.getClassLoader(),
                new Class[] { Collection.class }, new InvocationHandler() {
                    public Object invoke(Object proxy, Method method,Object[] args) throws Throwable {
                        ArrayList target = new ArrayList();
                        long beginTime = System.currentTimeMillis();
                        Object retVal = method.invoke(target, args);
                        long endTime = System.currentTimeMillis();
                        System.out.println(method.getName() + " running time of: " + (endTime - beginTime) + "ms");
                        return retVal;
                    }
                });
        proxy3.add("zxx");// 每调用一个add方法,invoke就被执行
        proxy3.add("lhm");
        proxy3.add("hjl");
        System.out.println(proxy3.size());
    }
}
    d.创建动态代理类:
        1)让动态生成的类成为目标类的代理:

public class MyAdvice implements Advice {
    long beginTime = 0;
    public void afterMethod(Method method) {
        System.out.println("开始啦!");
        long endTime = System.currentTimeMillis();
        System.out.println(method.getName() + " running time of " + (endTime - beginTime));
    }
    public void beforeMethod(Method method) {
        System.out.println("结束啦!");
        beginTime = System.currentTimeMillis();
    }
}

         2)object中有三个方法交给handler,分别是hashcode,equals,toString.其他的不委托,都有自己的实现方法。
public class ProxyDemo {   
    public static void main(String[] args) throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {  
        Class clazz = Proxy.getProxyClass(Collection.class.getClassLoader(), new Class[]{Collection.class});  
        Constructor[] cons = clazz.getConstructors();  
        for(Constructor con : cons){  
            System.out.println(con.getName()+"..."+con.getParameterTypes()[0].getName());  
        }  
        Method[] methods = clazz.getMethods();  
        for(Method method : methods){  
            System.out.println(method.getName()+"..."+method.getParameterCount());  
        }        
        Constructor constructor = clazz.getConstructor(InvocationHandler.class);  
        class Invocat implements InvocationHandler{   
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {   
                return null;  
            }                            
        }  
        Collection instance = (Collection)constructor.newInstance(new Invocat());  
        System.out.println(instance.toString());  
        instance.clear();  
        instance.hashCode();  
    }                    
}  
                     
         3)Proxy.newProxyInstance(ClassLoader,Class<?>,InvocationHandler)可以直接创建代理类对象。InvocationHandler接口中的invoke方法的作用 是对对象中方法进行操作,添加相应的操作。实现InvocationHandler接口,并计算各个方法的运行时间 
new InvocationHandler{  
    ArrayList target = new ArrayList();  
    public Object invoke(Object proxy,Method method,Object[] args)throws Throwable{                    
        long beginTime = System.currentTimeMillis();  
        Object retVal = method.invoke(target,args);  
        long endTime = System.currentTimeMillis();  
        System.out.println(endTime-beginTime);  
        return retVal;  
    }  
}

    e.实现类似spring的可配置的AOP框架:
        1)工厂类BeanFactory

public class BeanFactory {  
    Properties props = new Properties();  
    public BeanFactory(InputStream ips){  
        try {  
            props.load(ips);  
        } catch (IOException e) {  
            e.printStackTrace();  
        }  
    }                    
    public Object getBean(String name){  
        String className = props.getProperty(name);  
        Object bean = null;  
        try {  
            Class clazz = Class.forName(className);  
            bean = clazz.newInstance();  
        } catch (Exception e) {    
            e.printStackTrace();  
        }   
        if(bean instanceof ProxyFactoryBean){  
            Object proxy = null;  
            ProxyFactoryBean proxyFactoryBean = (ProxyFactoryBean)bean;  
            try {  
                Advice advice = (Advice)Class.forName(props.getProperty(name + ".advice")).newInstance();  
                Object target = Class.forName(props.getProperty(name + ".target")).newInstance();  
                proxyFactoryBean.setAdvice(advice);  
                proxyFactoryBean.setTarget(target);  
                proxy = proxyFactoryBean.getProxy();  
            } catch (Exception e) {    
                e.printStackTrace();  
            }  
            return proxy;  
        }  
        return bean;  
    }  
}  

        2)代理类ProxyFactoryBean
public class ProxyFactoryBean {
    private Advice advice;
    private Object target;
    public Advice getAdvice() {
        return advice;
    }
    public void setAdvice(Advice advice) {
        this.advice = advice;
    }
    public Object getTarget() {
        return target;
    }
    public void setTarget(Object target) {
        this.target = target;
    }
    public Object getProxy() {
        Object proxy3 = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),
                new InvocationHandler() {
                    public Object invoke(Object proxy, Method method,Object[] args) throws Throwable {
                        advice.beforeMethod(method);
                        Object retVal = method.invoke(target, args);
                        advice.afterMethod(method);
                        return retVal;
                    }
                });
        return proxy3;
    }
}

         3)测试类AopFrameworkTest
public class AopFrameworkTest {  
    public static void main(String[] args) throws Exception {  
        InputStream ips = AopFrameworkTest.class.getResourceAsStream("config.properties");  
        Object bean = new BeanFactory(ips).getBean("xxx");  
        System.out.println(bean.getClass().getName());  
        ((Collection)bean).clear();  
    }   
} 
    注:工厂类BeanFactory负责创建目标类或代理类的实例对象,并通过配置文件实现切换。其getBean方法根据参数字符串返回一个相应的实例对象,如果参数字符串在配置文件中对应的类名不是ProxyFactoryBean,则直接返回该类的实例对象,否则,返回该类实例对象的getProxy方法返回的对象。
        BeanFactory的构造方法接收代表配置文件的输入流对象,配置文件格式如下:(com.hanxuhui.blog.high_tech.generic.aop为包名)
        #xxx=java.util.ArrayList
        xxx=com.hanxuhui.blog.high_tech.generic.aop.ProxyFactoryBean //代理
        xxx.advice=com.hanxuhui.blog.high_tech.generic.aop.MyAdvice
        xxx.target=java.util.ArrayList//目标

            
----------------------ASP.Net+Unity开发.Net培训、期待与您交流! ----------------------
   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值