java:Spring框架2(bean的做用域,靜態工廠和實例工廠,自動裝配,動態代理)

1.bean的做用域,靜態工廠和實例工廠:java

 

 

  bean.xml:spring

<?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:ide

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:this

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:spa

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:hibernate

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:prototype

  

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();
    }
}
相關文章
相關標籤/搜索