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&amp;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()")


 

posted @ 2017-09-13 11:28  m97i  阅读(171)  评论(0编辑  收藏  举报