GIT地址:
Spring容器框架,可以管理web层,业务层,dao层,持久层。 可以配置各个组件并维护bean之间的关系。当需要使用某个bean的时候 ,使用getBean方法即可 ApplicationContext对象就对应那个ApplicationContext。xml文件 1.使用Spring不必new对象 。我们把创建对象的任务交给了spring框架。 2.在一个对象中,引用另外一个bean。(即spring管理对象关系)用ref。spring框架怎么被加载?spring中配置的bean怎么被加载?bean关系如何维护?
ClassPathXMLApplicationContext被加载的时候,相当关键:它执行的时候, spring容器对象被创建,同时applicationContext中配置的bean就会被创建。 内存中(结构是一个hashmap) : id有你配置的id=,然后有对象的实例。 ApplicationContext.put("userService",userService); 需要获取的时候就调用ac.getBean()方法即可 Dom4J是反射机制。ioc:所谓控制反转,就是把创建对象和维护对象之间的关系的权利,
从程序中转移到spring容器中(applicationContext.xml)。 di:spring设计者,认为di更能准确表示spring核心技术。大的项目,行业不一样。但是有很多可复用模块,如日志,等,之间配置就可以了。
但这些属于高级模块,也还是需要有底层的基础。可以写一个applicationContextUtil的方法,直接调用getBean方法。
MVC:
model层:包括业务层,dao层,持久层(一个项目中不一定都有这三个)。 view层:jsp Controller:Action。spring提倡接口编程,DI技术可以层与层之间的解耦。
UserService userService = ac.getBean("userService"); //同样一行代码,如果有两个类需要实现UserService对象时,只需更改配置 <bean id="userService" class="com.UserService1Impl"/> 切换为--> <bean id="userService" class="com.UserService2Impl"/> spring用到代理技术。 springXML文件中的bean是不能写class=接口的,只能写具体的实现类。 接口编程的优势就在这里:当有多个不一样的类实现同一个接口时,可用接口来实现。 这样Controller层对于Service层就完全解耦了,只要spring.xml文件配置即可。ApplicationContext应用上下文容器中获取bean和从bean工厂容器中,获取bean有什么不同?
1.上下文获取时:当我们实例化xml时,该文件中配置的bean被实例化; (前提是bean的配置是singleton,如果scope=prototype或者别的,也是延迟加载) 2.Bean工厂中获取的时候: BeanFactory factory = new XmlBeanFactory( new ClassPathResource("applicationContext.xml")); 此时没有实例化bean。 当factory.getBean()时,bean才被加载(延迟加载)。 一般是在移动设备中使用bean工厂方法,节省内存。 而大部分应用中,都是直接加载的。 获取ApplicationContext对象引用的三种方法: 1.ClassPathXMLApplicationContext 通过类路径 2.FileSystemXmlApplicationContext 通过文件路径来获取。 如("F:\JAVA INFORMATION\TARENA\xxxxx08\API") 不过记得要加转义字符:("F:\\JAVA INFORMATION\\TARENA\\xxxxx08\\API") 3.XmlWebApplicationContext 下次再说。 Bean的生命周期(applicationContext方式): 任何技术的生命周期是重点:因为只有当生命周期弄明白了,才能驾驭这个技术。 1.实例化(当我们的程序加载beans.xml文件),把我们的bean(前提是singleton) 实例化到spring容器中(默认无参构造函数被调用)。 2.调用Set方法,设置属性(必须要有一个set方法)。 3.若实现BeanNameAware接口,通过SetBeanName获取配置的id号:如userService。 4.若实现BeanFactoryAware接口,SetBeanFactory传递beanFactory对象。 5.若实现ApplicationContextAware接口,setApplicaitonContext获取上下文对象。 6.自己实现BeanPostProcessor接口,有before方法和after方法。 那么,每一个bean实例化之后,都会调用这个before和after 可以实现“记录每个对象实例化的时机”&“过滤每个调用对象ip的地址”等需求。 给所有对象添加一个属性,或者函数。(ApplicationContext.xml文件配置bean) (很有面向切面编程的味道)针对所有对象编程。 7.若实现BeanInisizing接口,则在before方法后调用afterPropertySet方法。 8.如果自己在<bean init-method="init"></bean>,则可以在bean定义自己的初始化方法。 9.使用bean 10.容器关闭 11.如果DisableBean接口,则实现destory()方法释放资源。——>用的比较少。 12.可在bean中配置destory_method方法。 小结:在实际开发中,1-2-6-9-10BeanFactory获取bean对象,其bean的生命周期:
比前面的少了几个,没有ApplicationContextAware,BeanPostProcessor__________
Bean装载: 尽量不要设置scope=‘prototype’,对性能影响较大。1.当然也可以在property中配置内部bean(用到较少)。
2.在bean的配置中,用一个parent,表示继承。 3.Map,List,Set,集合的配置: 如果Collection c= new ArrayList(); 那么c只能有collection的方法,没有ArrayList的方法。 但c是一个ArrayList的实例。 List是有序的,set是无序的。 List中可以有相同的对象。set中不能有相同的对象,直接覆盖掉了。Map的循环可以用entry(简单):
或者Map的循环也可以用迭代器。 Map的key相同的时候,也是覆盖。 4.Properties的使用和注入: <property> <prop key="pp1">abcd</prop> <prop key="pp2">44</prop> </property> property的循环也有两个:一个是entry,一个是enumeration 5.设置空注值:<null/>包在property中。自动装配bean的属性值:autowaire=五种(看文档)
1.no:默认 2.byName:autowire=byName表示根据名字来自动装载。 3.byType:顾名思义 4.constructor: 5.特殊bean分散配置:
2.PropertyPlaceholderConfigurer:SpringProperties获取配置的值。 也可以引入<context:property-placeholder location="dev/db.properties"/> ${url}叫做占位符**。--------------AOP------------
Aspect Oriented Programming 面向切面(方面)编程:是对所有对象,或者一类对象进行编程。 -核心特点:在不增加代码的基础上,还增加新功能。汇编语言:面向机器。伪机器指令 mov jump .
C语言:面向过程。最容易帮助人理解语言的本质。 系统语言,大部分都是用C语言写的,如操作系统,数据库,杀毒软件,防火墙。 aOP面向切面编程:面向多个对象编程 如多个service都有事务,则抽取出来。另外还有日志,安全。 aop在框架本身用的很多。 aop运行原理 + 案例: 1.aop的功能例如日志,可通过公共方法,在每一个需要的地方调用即可。 2.代理对象(spring提供proxyFactoryBean):通过代理接口来实现代理任务。 五种通知: 1.before(前置):实现MethodBeforeAdvice接口即可。 也是通过反射完成:当调用该代理方法时,即可知道参数等。 其中,applicationContext.xml需要配置 1.被代理的对象(目标对象) 2.前置通知(通知就是切面的实际实现) 3.代理对象(本身是ProxyFactoryBean对象实例) 3.1代理接口集 3.2织入通知 3.3配置被代理对象 <beans> <!-- 1.配置被代理的对象 --> <bean id="test1Service" class="com.Test1service"> <property name="name" value="wo"/> </bean> <!-- 2.配置前置通知,后置通知,环绕通知,异常通知,引入通知 --> <bean id="myMethodBeforeAdvice" class="com.MyMethodBeforeAdvice"> <!-- 3.配置代理对象,它本身是ProxyFactoryBean对象实例 --> <bean> <!-- 3.1理接口集 --> <property name="proxyInterfaces"> <list> <value>com.jos.TestServiceInterface</value> </list> </property> <!-- 3.2织入通知 --> <property name="interceptorNames"> ----相当于调用setInterceptorNames()方法 <value>myMethodBeforeAdvice</value> </property> <!-- 3.3配置被代理对象 --> <property name="target" ref="test1Service"/> </bean> </beans> (一个类实现了多个接口,那么这个接口之间是可以互相转的。) 2.3.4.5.后置通知,环绕通知,异常通知,引入通知。 SpringAOP中,通过代理对象去实现AOP技术的时候,获取的ProxyFactoryBean是什么类型? 答:返回的是一个动态代理对象。 1.如果实现了若干接口的话,Spring就使用(JDK)java.lang.reflct.Proxy代理 2.如果没有实现接口的话,Spring就使用CGLIB库生成目标对象。 对接口的代理,优于对类的代理,可以实现更加松耦合的系统。 对类的代理,作为备选。 不能对final方法进行通知。SpringAOP还有另外了两种实现方式:
1.一种方式是使用AspectJ提供的注解: package test.mine.spring.bean;import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; public class SleepHelper {public SleepHelper(){
} @Pointcut("execution(* *.sleep())") public void sleeppoint(){} @Before("sleeppoint()") public void beforeSleep(){ System.out.println("睡觉前要脱衣服!"); } @AfterReturning("sleeppoint()") public void afterSleep(){ System.out.println("睡醒了要穿衣服!"); } } 然后加上这个标签: <aop:aspectj-autoproxy/> 有了这个Spring就能够自动扫描被@Aspect标注的切面了2.第三种,常用的。
<aop:config>顶级配置元素,类似于<beans>这种东西 <aop:pointcut>定义一个切点 <aop:advisor> 定义一个AOP通知者 MYSQL 和redis 1.一个是存在内存中,一个是磁盘。 2.SQL语句不同。 3.性能上,redis更适合存放热点数据,比如用户登录信息及下单时用到的渠道、品种、合约信息。如果未命中缓存则去访问mysql 4.redis有大量数据结构如string,list,set,hashSet等Mybatis中:$
的like '%${ }%' 是用来做模糊查询时候用。Hibernate 与 Mybatis的区别
1.项目选择上,如果一个项目基本没有复杂查询,那么hibernate就很好用了。但如果复杂语句较多,Mybatis会更好。 2.工作量上,Mybatis需要手写SQL以及resultmap,而hibernate有良好的映射机制,无需关心sql映射,可以更专注于业务。 3.性能上,Hibernate会查询所有字段,稍微有点消耗,Mybatis可针对需要来指定。 4.日志,Hibernate有自己的日志,Mybatis需要使用log4j 5.缓存……SpringMVC中的注解:
1.@Controller BeanFactory & FactoryBean 的区别: BeanFactory是用来管理bean的工厂。 FactoryBean是实现了FactoryBean<T>的bean。根据该bean的id从beanFactory中获取的, 实际上是factoryBean的getObject返回的对象。如果要获取factorybean对象,可以在id前 加上&符号来获取。