zoukankan      html  css  js  c++  java
  • java:Spring框架2(bean的作用域,静态工厂和实例工厂,自动装配,动态代理)

    1.bean的作用域,静态工厂和实例工厂:

      bean.xml:

    <?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.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd">
        <!-- 
            bean的作用域可以使用scope属性指定,默认为单例(singleton),scope="singleton|prototype"
            singleton:单例,针对所有的请求只创建一个对象
            prototype:原型,针对每一次请求都会创建一个对象
            bean的生命周期
            1.如果作用域为singleton,当容器初始化时创建对象.
            2.如果作用域为prototype时,初始化容器时不会创建对象,当调用getBean方法时才真正创建。
         -->    
          <bean id="user" class="cn.zzsxt.entity.Userinfo" scope="singleton"></bean>
          <!-- 
              使用无参静态工程方法创建对象
              factory-method="静态工程方法的名称"
           -->
          <bean name="user2" class="cn.zzsxt.entity.UserFactory" factory-method="getInstatnce"></bean>
          <bean id="user3" class="cn.zzsxt.entity.UserFactory" factory-method="getInstatnce">
              <constructor-arg index="0" value="1"></constructor-arg>
              <constructor-arg index="1" value="zhangsan"></constructor-arg>
              <constructor-arg index="2" value="1234"></constructor-arg>
          </bean>
          
          <!-- 实例工厂方法 -->
          <!-- 1.创建工厂实例  init="初始化方法" destory="销毁的方法"-->
          <bean id="userFactory" class="cn.zzsxt.entity.UserFactory2" init-method="init" destroy-method="destory"></bean>
          <!-- 2.通过工厂实例的工厂方法创建对象 -->
          <bean id="user4" factory-bean="userFactory" factory-method="getInstatnce"></bean>
          <bean id="user5" factory-bean="userFactory" factory-method="getInstatnce">
              <constructor-arg index="0" value="1"></constructor-arg>
              <constructor-arg index="1" value="zhangsan"></constructor-arg>
              <constructor-arg index="2" value="1234"></constructor-arg>
          </bean>
    </beans>        

      beans2.xml:

    <?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.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd" default-autowire="byName">
        <bean id="userinfoDao" class="cn.zzsxt.dao.impl.UserinfoJdbcDaoImpl"></bean>
        <!-- 
            自动装配:autowire="byType|byName|constructor"
            byType:通过属性的类型进行自动装配:会根据属性类型在spring容器查找与其相同类型的bean,然后进行注入
                   要求:当前spring容器待注入的类型要唯一,否则将抛出NoUniqueBeanDefinitionException异常
               byName:通过属性名称进行自动装配:会根据属性名称在spring容器查找与其相同名称的bean,然后进行注入
                   要求:属性名称必须与spring容器中待注入的bean的id一致。
               constructor:通过构造方法进行自动装配:优先使用byName自动装配模式调用构造方法进行bean对象的构建.
            如果byName自动装配模式无法匹配所有的构造参数,则根据byType自动装配模式调用构造方法进行bean对象的构建.
            这时如果有多个同类型bean,会在构建bean对象时抛出异常    
               beans标签中的属性 : default-autowire
            在beans标签中可以通过配置属性default-autowire为所有bean子标签配置默认的自动装配模式,
             属性可选值与含义与bean标签的autowire属性一致. 参考配置文件如下:    
        -->
        <bean id="userinfoService" class="cn.zzsxt.service.impl.UserinfoServiceImpl" autowire="byName"></bean>
    </beans>        

     

      UserFactory:

    package cn.zzsxt.entity;
    
    public class UserFactory {
    
        /**
         * 无参的静态工程方法
         * @return
         */
        public static Userinfo getInstatnce(){
            return new Userinfo();
        }
        
        /**
         * 带参的静态工程方法
         * @param userId
         * @param userName
         * @param userPass
         * @return
         */
        public static Userinfo getInstatnce(int userId,String userName,String userPass){
            return new Userinfo(userId,userName,userPass);
        }
        
    }

      UserFactory2:

    package cn.zzsxt.entity;
    
    public class UserFactory2 {
        //初始化方法
        public void init(){
            System.out.println("init().....");
        }
        /**
         * 无参的实例工程方法
         * @return
         */
        public  Userinfo getInstatnce(){
            return new Userinfo();
        }
        
        /**
         * 带参的实例工程方法
         * @param userId
         * @param userName
         * @param userPass
         * @return
         */
        public  Userinfo getInstatnce(int userId,String userName,String userPass){
            return new Userinfo(userId,userName,userPass);
        }
        
        //销毁的方法
        public void destory(){
            System.out.println("destory()...");
        }
        
    }

      UserinfoServiceImpl:

    package cn.zzsxt.service.impl;
    
    import cn.zzsxt.dao.UserinfoDao;
    import cn.zzsxt.entity.Userinfo;
    import cn.zzsxt.service.UserinfoService;
    
    public class UserinfoServiceImpl implements UserinfoService {
        private UserinfoDao userinfoDao;
        
        public UserinfoServiceImpl(){
            
        }
        
        public void setUserinfoDao(UserinfoDao userinfoDao) {
            System.out.println("通过setter进行注入");
            this.userinfoDao = userinfoDao;
        }
    
        public UserinfoServiceImpl(UserinfoDao userinfoDao) {
            System.out.println("通过构造函数注入");
            this.userinfoDao = userinfoDao;
        }
    
        @Override
        public void save(Userinfo user) {
            System.out.println(userinfoDao);
            userinfoDao.save(user);
        }
    
    }

      TestInstanceFactory:

    package cn.zzsxt.test;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import cn.zzsxt.entity.Userinfo;
    
    public class TestInstanceFactory {
        public static void main(String[] args) {
            ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
            Userinfo user = (Userinfo)ac.getBean("user4");
            System.out.println(user);
            System.out.println("------------------");
            Userinfo user2 = (Userinfo)ac.getBean("user5");
            System.out.println(user2);
        }
    }

      TestScope:

    package cn.zzsxt.test;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import cn.zzsxt.entity.Userinfo;
    
    public class TestScope {
        public static void main(String[] args) {
            ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
            Userinfo user = (Userinfo)ac.getBean("user");
    //        Userinfo user2 = (Userinfo)ac.getBean("user");
    //        System.out.println(user==user2);
        }
    }

      TestStaticFactory:

      

    package cn.zzsxt.test;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import cn.zzsxt.entity.Userinfo;
    
    public class TestStaticFactory {
        public static void main(String[] args) {
            ApplicationContext ac = new ClassPathXmlApplicationContext("beans.xml");
            Userinfo user = (Userinfo)ac.getBean("user2");
            System.out.println(user);
            System.out.println("------------------");
            Userinfo user2 = (Userinfo)ac.getBean("user3");
            System.out.println(user2);
        }
    }

      TestAutoWire:

    package cn.zzsxt.test2;
    
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import cn.zzsxt.entity.Userinfo;
    import cn.zzsxt.service.UserinfoService;
    
    public class TestAutoWire {
        public static void main(String[] args) {
            ApplicationContext ac = new ClassPathXmlApplicationContext("beans2.xml");
            UserinfoService userinfoService = (UserinfoService)ac.getBean("userinfoService");
            Userinfo user = new Userinfo(1,"test","test");
            userinfoService.save(user);
        }
    }

     

    2.动态代理:

     

      

      ProductDaoImpl:

    package cn.zzsxt.dao.impl;
    
    import cn.zzsxt.dao.ProductDao;
    
    public class ProductDaoImpl implements ProductDao {
    
        @Override
        public void add() {
            System.out.println("利用hibernate执行商品的添加...");
        }
    
    }

      ProductDaoProxy:

    package cn.zzsxt.dao.impl;
    
    import cn.zzsxt.dao.ProductDao;
    
    public class ProductDaoProxy implements ProductDao {
        private ProductDao productDao;//被代理目标
        
        public ProductDaoProxy(ProductDao productDao) {
            this.productDao = productDao;
        }
    
        @Override
        public void add() {
            System.out.println("开启事务....");
            productDao.add();
            System.out.println("提交事务....");
        }
    
    }

      UserinfoDaoImpl:

    package cn.zzsxt.dao.impl;
    
    import cn.zzsxt.dao.UserinfoDao;
    
    public class UserinfoDaoImpl implements UserinfoDao {
    
        @Override
        public void save() {
            System.out.println("利用hibernate执行了用户新增...");
        }
    
    }

      UserinfoDaoProxy:

    package cn.zzsxt.dao.impl;
    
    import cn.zzsxt.dao.UserinfoDao;
    
    public class UserinfoDaoProxy implements UserinfoDao {
        private UserinfoDao userinfoDao;//被代理目标
        
        public UserinfoDaoProxy(UserinfoDao userinfoDao) {
            this.userinfoDao = userinfoDao;
        }
    
        @Override
        public void save() {
            System.out.println("开启事务....");
            userinfoDao.save();
            System.out.println("提交事务....");
        }
    }

      

      JDKProxy:(基于接口的实现)

    package cn.zzsxt.proxy;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    /**
     * 
     * JDK动态代理:使用前提(基于接口的实现)
     * JDK动态代理:本质上生产了一个代理类,该代理与被代理目标实现相同的接口,
     * 当前用户访 问代理类中的方法时,将委派InvacationHandler中的invoke()方法进行处理,
     * 在invoke()方法中添加业务处理代理和回调被代理目标中方法。
     * @author Think
     *
     */
    public class JDKProxy implements InvocationHandler{
        private Object target;//被代理目标
        
        public JDKProxy(Object target){
            this.target=target;
        }
        
        /**
         * 生成代理
         */
        public Object  createProxy(){
            /**
             * loader - 定义代理类的类加载器
               interfaces - 代理类要实现的接口列表
               h - 指派方法调用的调用处理程序 
             */
            return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
        }
        /**
         * proxy - 在其上调用方法的代理实例
         * method - 对应于在代理实例上调用的接口方法的 Method 实例
         * args - 包含传入代理实例上方法调用的参数值的对象数组
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("开启事务....");
            Object returnValue = method.invoke(target, args);//回调被代理目标的方法
            System.out.println("提交事务....");
            return returnValue;
        }
        
    }

      TestJDKProrxy:

    package cn.zzsxt.proxy;
    
    import cn.zzsxt.dao.ProductDao;
    import cn.zzsxt.dao.UserinfoDao;
    import cn.zzsxt.dao.impl.ProductDaoImpl;
    import cn.zzsxt.dao.impl.UserinfoDaoImpl;
    
    public class TestJDKProrxy {
        public static void main(String[] args) {
            JDKProxy proxy = new JDKProxy(new UserinfoDaoImpl());
            UserinfoDao userinfoDao = (UserinfoDao)proxy.createProxy();//创建代理
            userinfoDao.save();
            System.out.println("-------------------");
    //        JDKProxy proxy2 = new JDKProxy(new ProductDaoImpl());
    //        ProductDao productDao = (ProductDao)proxy2.createProxy();//创建代理
    //        productDao.add();
            
        }
    }

      GglibProxy:(基于父类实现:cglib动态代理)

    package cn.zzsxt.proxy2;
    
    import java.lang.reflect.Method;
    
    import net.sf.cglib.proxy.Enhancer;
    import net.sf.cglib.proxy.MethodInterceptor;
    import net.sf.cglib.proxy.MethodProxy;
    
    /**
     * cglib:基于父类实现:cglib动态代理. 
     * 本质上动态生成了一个被代理目标的子类(要求被代理类不是final修饰的类),
     * 通过多态实现功能的加强,当访问代理中的方法时,
     *  委派给MethodInteceptor中的处理程序(intercept方法)进行出来, 
     *  在处理程序中添加了业务逻辑和回掉了被代理目标中的方法。
     * 
     * @author Think
     * 实现步骤:
     * 1.添加cglib依赖的jar文件
     *   cglib-2.2.2.jar,asm-3.3.1.jar,asm-util-3.3.1.jar,ant-1.6.2.jar
     * 2.创建Enhancer对象
     * Enhancer enhancer = new Enhancer();
     * 3.设置基类(父类)
     * enhancer.setSuperclass(target.getClass());
     * 4.设置回调接口
     *    enhancer.setCallback(this);//MethodInterceptor实现类
     * 5.创建动态代理
        enhancer.create();
     * 
     *
     */
    public class GglibProxy implements MethodInterceptor{
        private Object target;
        
        public GglibProxy(Object target){
            this.target=target;
        }
        
        public Object createProxy(){
            //创建Enhancer对象
            Enhancer  enhancer = new Enhancer();
            //设置基类
            enhancer.setSuperclass(target.getClass());
            //设置回调接口
            enhancer.setCallback(this);
            //创建代理
            return  enhancer.create();
            
        }
    
        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            System.out.println("开启事务.....");
            Object value = method.invoke(target, args);//回掉被代理目标中的方法
            System.out.println("提交事务....");
            return value;
        }
        
        
        public static void main(String[] args) {
            GglibProxy cglibProxy = new GglibProxy(new OrderDao());
            OrderDao orderDao = (OrderDao)cglibProxy.createProxy();
            orderDao.add();
        }
    
    }

      OrderDao:

    package cn.zzsxt.proxy2;
    
    public class OrderDao {
        public void add(){
            //System.out.println("开启事务...");
            System.out.println("添加了订单....");
            //System.out.println("提交事务...");
        }
    }

      OrderDaoProxy:

    package cn.zzsxt.proxy2;
    
    public class OrderDaoProxy extends OrderDao{
        
        @Override
        public void add() {
            System.out.println("开启事务..");
            super.add();
            System.out.println("提交事务...");
        }
        
        
        public static void main(String[] args) {
    //        OrderDao orderDao = new OrderDao();
            OrderDao orderDao = new OrderDaoProxy();
            orderDao.add();
        }
    }

      

      

  • 相关阅读:
    学习计划 23月
    bash学习笔记
    bash 中 while读取文件并通过 ssh执行命令出现的问题及解决方法
    bash 学习笔记2
    fedora 启动 openssh
    lesson5 键盘的应用
    第十三章 int指令
    第十五章 外中断
    第十二章 内中断
    第十四章 端口
  • 原文地址:https://www.cnblogs.com/kuangzhisen/p/7420511.html
Copyright © 2011-2022 走看看