学习Spring笔记二

动态代理模式

静态代理:代码复用不高,将来维护时难

动态代理:静态代理上提供的,因为代理比较常用,JDK提供了一套生成代理类的方式proxy类(遇到什么问题先看JDK有没有提供解决方法),动态代理的特点是把增强的功能包装成一个类,这个类要实现InvocationHandler接口,看到InvocationHandler要条件反射想到动态代理。代理类实现增强功能的类都需要委托类做属性,因为需要它们来做参数,写到有参构造里。不论静态、动态都需要!



实例代码

1.dao.impl下建立UserDaoFactory类

public class UserDaoFactory{

UserDao userDao= new UserDaoImplForMysql();    //这个委托类,作为回调函数的参数。学习框架后,这样把类作为属性,传值的方式越常见

public static UserDao getInstance(){

UserDao proxy =(UserDao)Proxy.newProxyInstance(

UserDao.class.getClassLoader(),     //获得字节码

UserDaoImplForMysql.class.getInterfaces(),     //代理类和委托类实现同一接口(相似性),这里是获取代理类、委托类的接口

new LogHandler(userDao)  //LogHandler类是代理类,userDao是委托类,在这里把他们动态组合成一个代理,所以这是动态代理的重点(这两个类需要分别实现)

);

return proxy;

}

public static void main(String[ ]  args){

UserDao dao = UserDaoFactory.getInstance();    //UserDaoFactory是不用new的,因为getInstance方法是static的,只需要通过UserDaoFactory来引用即可,不用new

dao.add();

}

}




2.建立一个handler包,里面有一个LogHandler类,内容如下

public class LogHandler implements InvocationHandler{    //实现InvocationHandler接口,这是个动态代理类

public Object obj;       //委托类对象的引用


public LogHandler(Object obj){     //有参构造 ,为了嵌套委托类而写

super();

this.obj = obj;

}


public Object invoke(Object proxy,Method method,Object[ ]  args)throws Throwable {   //实现InvocationHandler接口会实现invoke方法

System.out.println("系统日志!!!");

method.invoke(obj,args);       //这里的invoke方法可以这样理解,客户类action调用UserDaoFactory的getInstance方法,这个方法的Proxy.newProxyInstance里的第三个参数去调用此invoke方法,然后这个方法返回给Proxy.newProxyInstance,再返回给getInstance,再一层层向上返回。先一层层向下调用 ,然后按顺序再返回。

return null;

}

}




3.另外还需要接口UserDao,UserDaoImplForMysql,和其它实例中的一样。实例结束,可以运行main方法测试


解释一下动态代理

动态代理是通过proxy对象把委托类(UserDaoImplForMysql) 和代理类(LogHandler) 组合了起来!!

action调用的是Factory中的proxy对象的newProxyInstance方法,它里面的回调函数调用代理类来执行作为参数的委托类“new LogHandler(userDao)”  userDao委托类的接口,LogHandler代理类。(回调函数要好好练一练)

动态代理默认会景程委托类的所有方法,如果你在UserDao接口里添加del方法,并且它的实现类也实现了该方法,在main方法添加dao.del();执行时会也在del外增强LogHandler的功能。



动态代理的proxy对象的详细解说

共3个参数,第一个classloader,第二个是获取接口(可以对这个接口下的实现类造成影响),第三个是回调函数,它的参数是委托类。在当前类显示的是userDao,在LogHandler类里是obj引用。$ProxyN 是jdk制作出来的代理类的命名规则。看到控制台打印这种形式的应该知道这是JDK的代理类。


代理类两个原则:相似性和增强

动态代理:委托类必须有接口,代理类才能和委托类相似。因为接口就是对于这个类的描述。就像一张图纸定义这个类的。缺点是必须和有接口。



只要是远程方法之间调用,不同语言之间沟通,两台机器之间沟通。这些东西全都是代理。所以代理模式非常重要,它是一个思维的基础,没有这个思维的基础,脑海里面就建立不起来这个模型。



————————动态代理   end ——————————————————





Spring正题——————

什么项目适合用Spring?

中型最合适,大型分布式项目用EJB

Spring+webservice也可以实现分布式项目(分布式项目是指,一个子系统在北京,另一个子系统在海南这样的项目)



Spring的helloworld代码start——————

1.下载jar包(jar包中docs/MVC-step-by-step是教SpringMVC的)

它的lib包下有好多其它的框架的包,因为Spring可以和它们整合,Spring自己的jar包则放在了dist文件夹下面(一般下载下来的jar包,核心文件常会放在dist文件夹下)

spring.jar包需要拷贝,modules文件夹下面的jar包是把spring.jar包分解开的小jar包,你可以看情况选择用哪个。

spring-sources.jar也一起拷贝到项目中。


a)  把spring.jar和spring-sources.jar拷贝到项目下

b)  把jarkarta-commons的commons-logging.jar拷贝到项目下



2.src下建立beans.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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">


<bean id="userDao" class="com.bjsxt.dao.UserDao"  lazy-init="true"></bean> //这个bean要对应到项目中,要写个userDao类,默认是饿加载,要写lazy-init="true"变成懒加载

</beans>




3.建立dao包,包下建立UserDao类

public class UserDao{

public UserDao(){

System.out.println("init......");

}

public void add (){

System.out.println("Hello Spring");

}

}



4.建立test包,包下建立Test类,来创建spring提供的IOC容器,当然,不是我们自己手写,和代理一样,JDK有提供相关API(JAVA这么规范、强大的语言,很多都提供了接口,其实很简单)

public class Test{

//IOC像一个大工厂,单例、工厂、代理、IOC模式它都包括

public static void main(String[ ] args){

ApplicationContext ac = new ClassPathXmlApplicationContext(

new String[ ] {"beans.xml"} //AC容器在读取beans.xml配置文件

);

UserDao userDao = (UserDao)  ac.getBean("userDao");     //AC容器从beans.xml中找到userDao,通过反射实例化UserDao,然后使用它的方法。通过IOC容器来统一实例化,达到控制对象与对象之间的关系,而不是你想实例化谁就实例化谁。

userDao.add();

}

}


Spring的helloword  end——————————


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值