GIT地址:https://github.com/BravenZhou/spring-ioc-easy
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-10
BeanFactory获取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;
@Aspect
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前
加上&符号来获取。