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();
    }
}
    

  

  

 

 

   

 

 

  

 

posted @ 2020-08-12 21:45  suke_123  阅读(99)  评论(0编辑  收藏  举报