spring
互相之间的引用通过接口来体现
不new对象 通过容器获得对象
spring两大核心===============
控制反转IOC/依赖注入DI
面向切面AOP
=============================
applicationContext.xml spring配置文件->
<bean id="conDisk" class="dao.impl.ConDisk">
<property name="data">
<value> 值 </value>
</property>
</bean>
//data是类的属性 value是赋值
读配置文件返回对象
ApplicationContext context=new ClassPathXmlApplicationContext("*.xml");
context.getBean("biz"); //返回Object
日志==========
log4j包
Logger logger=Logger.getLogger( 当前类.class);
logger.debug(String);
//logger.error(String);
AOP=================> 添加xsd
增强Advice //比如日志Logger 在方法的前后添加
切入点Pointcut //某个类的方法的增强功能的位置
连接点Joinpoint
切面Aspect //指的是增强和切入点的组合
代理Proxy
目标对象Target //比如增强的对象
织入Weaving //编码过程
<bean id="serviceLogging" class="com.pb.aop.ServiceLogging"></bean>
<bean id="userService" class="com.pb.service.UserService"></bean>
<aop:config>
<aop:pointcut id="servicePointcut" expression="execution(public * com.pb.service.*.*(..))" />
<aop:aspect ref="serviceLogging">
<aop:before method="beforeService" pointcut-ref="servicePointcut"/>
<aop:after-returning method="afterReturning" pointcut-ref="servicePointcut" returning="returnVal"/>
<aop:after-throwing method="afterThrowing" pointcut-ref="servicePointcut" throwing="ex"/>
<aop:after method="after" pointcut-ref="servicePointcut"/>
<aop:around method="around" pointcut-ref="servicePointcut"/>
</aop:aspect>
</aop:config>
表达式匹配规则 针对方法====================
public * addUser(com.pb.entity.User) //匹配所有返回值的类型的addUser方法
public void *(com.pb.entity.User) //匹配公共无返回值的所有方法
public void addUser(..) //匹配所有参数的方法
* com.pb.service.*.*(..) //匹配com.pb.service包下所有类的所有方法
* com.pb.service..*(..) //匹配com.pb.service包及子包下所有类的所有方法
增强方法的参数 joinpoint jp======================
jp.getTarget() //得到增强目标的类名
jp.getSinature().getName() //得到增强目标的方法名
jp.getArgs()[0] //得到增强目标的第一个参数的值
方法之后执行的增强方法可以得到返回值 ===========================
aop:after-returning returning="result"
在方法里增加返回值
增加增强方法的参数并且调用
spring AOP的主要工作========================
通过Advice增强 描述横切逻辑和方法的具体织入点(方法前,后,两端等)
通过Pointcut切点 指定在哪些类的哪些方法上织入横切逻辑
通过Aspect切面 将Pointcut切点和Advice增强两者结合起来
利用jdk动态代理结束或GCLib为目标Bean创建织入切面的代理对象
AOP的动态代理================
jdk动态代理 面向接口设计
java.lang.reflect.InvocatuinHandler 定义增强 invoke方法的调用
java.lang.reflect.Proxy 创建代理对象
CGLib动态代理
JAVA源代码--->编译后的字节码文件CLASS-->运行时虚拟机JVM加载CLASS到内存
不需要源代码 直接生成二进制字节码文件
继承重写 需要代理的类不能被常量final修饰
面向接口
一个接口做代理 为所有实现类增强
创建速度快 执行速度慢
面向具体类型
在运行过程中 动态创建子类 实现代理 在子类中调用代理 调用原装核心业务 实现增强
不能有final修饰 无法继承重写
创建速度慢 执行速度快
spring框架决定调用代理
如果是接口和实现类 创建jdk动态代理
如果是没有接口和实现类 则创建CGLIB代理
手动设置代理
在spring配置文件中
<aop:config proxy-target-class="true"> //默认是false
</aop:config>
true直接对目标对象做代理 ---- CGLIB
========================================================
属性注入的方式->
1.设值注入(需要等Servicebean对象创建完毕之后才会进行注入属性,通过无参构造方法实例化)
public void setDao(ITestDao dao){...}
<property name="userDao" ref="userDao"></property>
2.构造注入(构造对象和注入属性都可以在构造方法中进行,构造方法中可以直接调用属性及对象属性方法)
public class TestBizImpl implements ITestBiz{
public TestBizImpl(){}
public TestBizImpl(ITestDao dao){this.dao=dao}
}
<bean id="userDao" class="dao.impl.UserDaoImpl"
p:sessionFactory-ref="sessionFactory">
</bean>
//可以通过index和type明确指定参数的位置
<bean id="userService" class="service.impl.UserServiceImpl">
<!-- 一个构造参数对应一个constructor-arg标签 按类型 -->
<constructor-arg index="0">
<ref bean="userDao">
</constructor-arg>
<constructor-arg index="1" type="java.lang.String">
<value>112</value>
</constructor-arg>
</bean>
3.使用p命名空间注入属性
xmlns:p="http://www.springframework.org/schema/p"
对于引用属性 p:属性名-ref="Bean的id"
对于直接量(基本数据类型,字符串)属性 p:属性名="属性值"
<bean id="userDao" class="dao.impl.UserDaoImpl"
p:sessionFactory-ref="sessionFactory"></bean>
<property name="name">
<value>P&G</value>
</property>
<property name="age">
<value>123</value>
</property>
<property name="dao"> <!-- biz.setDao(testDao) -->
<ref bean="testDao"/>
</property>
<property name="dao"> <!-- biz.setDao(new TestDao()) -->
<bean class="dao.testDao"/>
</property>
注入直接量:使用<value>标签实现
引用bean:使用<ref>标签实现
使用内部bean:<ref bean="testDao"/> 查找范围大
<ref local="testDao"/>查找当前配置文件的id
注入集合类型的属性:<list><props><set><map>标签实现
注入null和空字符串值:使用<null/>注入null值 || <value></value>注入空字符串
========================================================
自动装配 AutoWire
no 默认值. spring默认不进行自动装配,必须指定依赖对象
byName 根据属性名自动装配. spring自动查找与属性名相同的bean的id,如果找到自动注入,否则什么也不做
byType 根据属性类型自动装配. spring自动查找与属性类型相同的bean,如果找到唯一一个,则自动装配;如果找到多个属性类型相同的bean,则抛出异常;没找到就什么也不做
constructor 针对构造方法,如果spring找到与构造方法的参数类型相同,则通过构造注入该依赖对象;找不到抛出异常
<bean id="userBiz" class="biz.UserBiz" autoWire="byName">
或者设置全局自动装配
在顶部beans标签中 <beans ..http..." default-autowire="byName">
行内设置自动装配 优先级 大于全局配置
==================================
aop
public void around(ProceedingJoinPoint jp)
//可以判断是否执行被增强的方法
if(...)
jp.proceed();//执行被增强的方法
------------------------------------------
Advisor 增强处理的实现
要实现MethodBeforeAdvice并重写before方法
配置
<bean id="serviceBeforeAdvisor" class="aop.ServiceBeforeAdvice"></bean>
<aop:config>
<aop:pointcut id="servicePointcut" expression="execution(public * service.*.*(..))"></aop:pointcut>
<aop:advisor advice-ref="serviceBeforeAdvisor" pointcut-ref="servicePointcut"></aop:advisor>
</aop:config>
前置增强实现MethodBeforeAdvice
后置增强实现AfterReturningAdvice
坏绕增强实现MethodInterceptor
异常增强实现ThrowsAdvice
public void afterThrowing(Method arg0,Objece[] arg1,Object arg2,
IOException e){}
===================================================
使用注解实现IOC
@Component 实例化pojo类 相当与<bean id="" class="">
@Repository 用于标注Dao类
@Service 用于标注业务类
@Controller 用于标注控制器类
@Scope("prototype") //多例,默认不写是单例
@Repository("userDao")
public class UserDao Implements Dao{
}
对属性注解, 在属性/set方法/构造方法上添加
@AutoWired //默认按类型注入<property>
@Qualifier("testDao") //按名字注入
在配置文件中 引入schema->context
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
<!-- 扫描包中带注解的类 -->
<context:component-scan base-package="service,dao"></context:component-scan>
定义切面 在增强类
@Aspect
public class TestLogger(){
@Before("execution(public * service..*(..))")
public void before(){
System.out.println("before前置增强方法");
}
@After("execution(public * service..*(..))")
public void after(){
System.out.println("after后置增强方法");
}
@Around("execution(public * service..*(..))")
public void around(ProceedingJoinPoint pjp){
pjp.proceed();
}
}
<bean class="aop.TestLogger">
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
在类中定义切点
@Pointcut("execution(public * service..*(..))")
public void pointcut(){};
@Before("pointcut()")