Spring IOC和aop的原理及实例详解
这篇文章主要介绍了SpringIOC和aop的原理及实例详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。特点是面向接口编程,松耦合。
1:IOC(控制反转)别名(DI:依赖注入)
首先来一段ioc的实现原来代码:
publicclassClassPathXmlApplicationContextimplementsBeanFactory{ privateMapbeans=newHashMap (); //IOCInverseofControlDIDependencyInjection publicClassPathXmlApplicationContext()throwsException{ SAXBuildersb=newSAXBuilder(); //解析xml配置文件 Documentdoc=sb.build(this.getClass().getClassLoader().getResourceAsStream("beans.xml")); Elementroot=doc.getRootElement();//获取根元素 Listlist=root.getChildren("bean");//根元素下的子元素 for(inti=0;i )element.getChildren("property")){ Stringname=propertyElement.getAttributeValue("name");//userDAO Stringbean=propertyElement.getAttributeValue("bean");//u ObjectbeanObject=beans.get(bean);//UserDAOImplinstance StringmethodName="set"+name.substring(0,1).toUpperCase()+name.substring(1); System.out.println("methodname="+methodName); Methodm=o.getClass().getMethod(methodName,beanObject.getClass().getInterfaces()[0]); m.invoke(o,beanObject); } } } publicObjectgetBean(Stringid){ returnbeans.get(id); } }
//xml文件
以上代码实现了将UserDAOImpl注入到userService.
值得注意的是:以上操作都是spring帮我们实现的,我们只需要理解如何配置即可。
spring还提供了bean的生存周期和范围属性:
scope:singleton(单例,即每次调用的对象都为同一个)。prototype(原型,即以bean对象为原型,每次new一个新对象出来)
init-method="init"destroy-method="destroy"lazy-init="true"(延迟初始化bean,即spring启动时,不初始化bean,当需要使用时才实例化,作用:但spring启动缓慢时可使用)
现在基本都是用注解实现,但只要能明白spring是如何实现bean的注入,基本原理都是一样的。spring在中间的作用就是帮我们实现元素之前的注入,谁注入到谁就需要用到不同的注解了。
AOP(切面编程)
首先还是先来一段代码
定义一个InvocationHandler的实现类
publicclassUserServiceTest{ @Test publicvoidtestAdd()throwsException{ BeanFactoryapplicationContext=newClassPathXmlApplicationContext(); UserServiceservice=(UserService)applicationContext.getBean("userService"); Useru=newUser(); u.setUsername("zhangsan"); u.setPassword("zhangsan"); service.add(u); } @Test publicvoidtestProxy(){ UserDAOuserDAO=newUserDAOImpl(); LogInterceptorli=newLogInterceptor(); li.setTarget(userDAO); UserDAOuserDAOProxy=(UserDAO)Proxy.newProxyInstance(userDAO.getClass().getClassLoader(),userDAO.getClass().getInterfaces(),li); userDAOProxy.delete(); userDAOProxy.save(newUser()); }
调用测试类,service和DAO实现类没有贴出来,就是打印一句话出来表现方法执行了。
publicclassLogInterceptorimplementsInvocationHandler{ privateObjecttarget; publicObjectgetTarget(){ returntarget; } publicvoidsetTarget(Objecttarget){ this.target=target; } publicvoidbeforeMethod(Methodm){ System.out.println(m.getName()+"start"); } @Override publicObjectinvoke(Objectproxy,Methodm,Object[]args) throwsThrowable{ beforeMethod(m); m.invoke(target,args); returnnull; } }
以上代码简单的实现了一个动态代理,并执行了自己的一段逻辑。
那么aop是如何实现切面编程的呢,就是通过动态代理。当然这也是spring来实现的,而我们需要做的就是知道如何编写编织语法。
- JoinPoint:切入点
- PointCut:切入点的集合
- Aspect:切面
- Advice:相当于Aspect的before
- Around:周围,环绕(需要带参数ProceedingJoinPointjp)
需要注意的是:被产生代理的对象需要现实接口spring才能产生代理对象,默认使用javase中的InvocationHandler和proxy两个类产生代理对象,若没有实现接口,则需要另外引入一个jar包(cglib-nodep-2.1_3.jar);他是通过二进流的方式产生代理对象。
那么spring帮我们做了什么?
1:充分利用javase中的反射机制帮助我们对对象的注入,即IOC,
2:也是javase中的动态代理帮助我们实现切面编程,当然我们也需要熟悉一下asceptj的切入语法。这就是aop。
所以这里可以总结一下,javase的特点有反射,动态代理,(这里面必然会用到多态,动态绑定)
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。