• Spring02


    1、

    application.xml  中容器管理bean需要去扫描

    <?xml version = "1.0" encoding = "UTF-8"?>
    <beans xmlns = "http://www.springframework.org/schema/beans"
       xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation = "http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/aop 
       http://www.springframework.org/schema/aop/spring-aop-4.0.xsd 
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context.xsd">
     
         <!-- 扫描指定包下的带有Component标签的类,纳入spring管理 -->
        <context:component-scan base-package="com.mashibing.spring"></context:component-scan>
    </beans>

      

     先通过类型去装配类,如果类型找不到,比如这个类型为某一个接口,但是它的实现类有多个,那么在这个类型下面再用@Qualifier指定实现类名称。

    使用场景:https://blog.csdn.net/qq_36567005/article/details/80611139

    2、问为什么实体类不能用单例?

      考虑线程安全问题:

      从表到usr对象之间的映射叫ORM图

      

       一次请求一个线程,一定是创建两个实体类对象,如果参数写成不是private的,那么变量可能会被改变,存在线程安全问题。

       

      实体类对象用“prototype”,每次都是new出来的。

      

    /**
     * ORM映射
     *     线程安全
     * @author 14308
     *
     */
    @Component
    @Scope("prototype")
    public class User {
        
        //设置默认值    简单的属性注入
        @Value("zhangsan")
        private String loginName;
        
        @Value("123123")
        private String password;
        //注入对象引用的  
        @Autowired
        private Pet pet;
    
    }

      

     都可以用@Component代替

    3、静态代理

      

       

    package com.mashibing.spring;
    
    public interface Human {
        public void eat(); 
    }
    
    _______________________________________________
    package com.mashibing.spring;
    
    public class Girl implements Human{
        public void eat() {
            System.out.println("Em mmm... mm..");
        }
    }
    
    ________________________________________________
    package com.mashibing.spring;
    
    public class ProxyGirl implements Human{
        
        
        private Human human;
        
        public ProxyGirl() {
            
        }
    
        public ProxyGirl(Human human) {
            super();
            this.human = human;
        }
        
        @Override
        public void eat() {
            System.out.println("chiqian");
            human.eat();
            System.out.println("chihou");
        }
    }
    
    __________________________________________
    package com.mashibing.spring;
    
    import org.apache.commons.lang3.builder.ToStringStyle;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    
    public class TestGetBean {
        public static void main(String[] args) throws Exception{
        
            Girl girl = new Girl();
            
            Human proxyGirl = new ProxyGirl(girl);
            proxyGirl.eat();
        }
    }
        

       从静态代理的使用上来看:1.代理类一般要持有一个被代理的对象的引用。2.对于我们不关心的方法,全部委托给被代理的对象处理。3.自己处理我们关心的方法。

      其优点表现为:在不修改目标对象的前提下,可以通过代理对象对目标对象功能扩展

      代理使客户端不需要知道实现类是什么,怎么做的,而客户端只需知道代理即可(解耦合),对于如上的客户端代码,RealInterner() 可以应用工厂将它隐藏。

      缺点为:代理类和委托类实现了相同的接口,代理类通过委托类实现了相同的方法。这样就出现了大量的代码重复。如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度。

      代理对象只服务于一种类型的对象,如果要服务多类型的对象。势必要为每一种对象都进行代理,静态代理在程序规模稍大时就无法胜任了。

    4、动态代理

    • 面向与接口,jdk的动态代理
    package com.mashibing.spring;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    import org.apache.commons.lang3.builder.ToStringStyle;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    
    public class TestGetBean {
        public static void main(String[] args) throws Exception{
        
            final Girl girl = new Girl();
            /**
             * 参数1-Girl.class.getClassLoader()代表通过反射,Girl被new出来了,可以通过Girl的字节码文件反着找Girl类
             * 参数2-Girl.class.getInterfaces()代表通过反射,找出Girl的所有接口
             * 参数3-new InvocationHandler()是拦截方法执行的
             * 
             */
            Human proxyGirl = (Human) Proxy.newProxyInstance(Girl.class.getClassLoader(), Girl.class.getInterfaces(), new InvocationHandler() {
                
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println(method.getName());
                    if (method.getName().equals("bath")) {
                        System.out.println("偷看洗澡");
                        Object invoke = method.invoke(girl, args);
                        System.out.println("6了6了");
                        return invoke;
                    }else {
                        System.out.println("饭前");
                        Object invoke = method.invoke(girl, args);
                        System.out.println("饭后");
                        return invoke;
                    }
                }
            });
            proxyGirl.eat();
            System.out.println("---------------------");
            proxyGirl.bath();
        }
    }
        

    •  CGlib动态代理

     CGLibFactory类

    package com.mashibing.spring;
    
    import java.lang.reflect.Method;
    
    import org.springframework.cglib.proxy.Enhancer;
    import org.springframework.cglib.proxy.MethodInterceptor;
    import org.springframework.cglib.proxy.MethodProxy;
    
    public class CGLibFactory implements MethodInterceptor{
    
        private Object target;
        
        public CGLibFactory() {
            super();
        }
        
        public CGLibFactory(Object target) {
            this.target = target;
        }
        
        /**
         * 创建代理对象
         * @return
         */
        public Object createProxy() {
            Enhancer enhancer = new Enhancer();
            //设置父类
            enhancer.setSuperclass(Girl.class);
            enhancer.setCallback(this);
            return enhancer.create();
        }
        
        /*
         * 拦截器 
         * Object obj, Method method, Object[] args, MethodProxy proxy
         * obj是被传过来的,第二个method是动态代理对象要执行的方法,args是方法的参数,proxy是方法的代理
         */
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println("钱");
            method.invoke(target, args);
            System.out.println("后");
            return null;
        }
    
    }

    Test类

    package com.mashibing.spring;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    import org.apache.commons.lang3.builder.ToStringStyle;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    
    public class TestGetBean {
        public static void main(String[] args) throws Exception{
        
            Girl girl = new Girl();
            Girl proxyGirl = (Girl)new CGLibFactory(girl).createProxy();
            
            proxyGirl.eat();
            System.out.println("------------");
            proxyGirl.bath();
        }
    }
        

      

      

       

      

  • 相关阅读:
    Express入门
    nodejs入门
    css实现点点点效果
    定时器详解和应用、js加载阻塞、css加载阻塞
    栈内存和堆内存有什么区别?
    webpack入门
    Ubuntu常用命令集合
    HTTP缓存机制
    125. 验证回文字符串
    算法的时间复杂度和空间复杂度(js版)
  • 原文地址:https://www.cnblogs.com/su-ke/p/13493211.html
Copyright © 2020-2023  润新知