spring学习笔记

spring

作者:Yjanuary


@基本配置

<bean id=" " class=" "></bean>
<bean> :配置需要创建的对象
id :用于之后从spring容器获得实例时使用的
class :需要创建实例的前限定名称

@xml解析:

classPathXmlApplicationContext :用于加载,解析classpath下xml

@setter注入
创建service

<bean id="bookServiceId" class="">
   <property name=" bookDao" ref="bookDaoId "></property>
</bean>

创建dao实例

<bean id=" dao实例" class=" "></bean>

模拟spring执行过程
创建service实例:

BookService bookService = new BookServiceImpl() IOC

创建dao实例 :

BookDao bookDao = new BookDaoImpl() Ioc

将dao设置给service :

 bookService.setBookDao(bookDao) di

property 用与进行属性注入
name :bean的属性名 ,通过setter方法获得
setBookDao ## >BookDao ##> bookDao
ref :另一个bean的id值的引用

BeanFactory:用于生成任意bean,采用延迟加载,第一次getBean时才会初始化Bean
ApplicationContext :是BeanFactory的子接口,功能更强大

BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource(xmlPath));

@实例化方式
3种实例化方式:默认构造,静态工厂,实例工厂

1:默认构造 :必须提供默认构造

<bean id=" " class=" "> 

2:静态工厂:用于生成实例对象,所有的方法必须是static

3:工厂

 public class MyBeanFactory{
    public static UserService createService(){
       return bew UserServiceImpl();
    }
 }

spring配置

 <bean id="userServiceId" class="com.shikun.inject"            factory-method="createService">
 </bean>

@Bean 种类
1:普通bean :

<bean id=" " class=" ">

2:FactoryBean:是一个特殊的bean,具有工厂生成对象能力,只能生成特定的对象
bean必须使用FactoryBean接口,此接口提供方法getObject()用于获取特定bean
3:BeanFactory 和 FactoryBean对比
BeanFactory:工厂,用于生成任意bean
FactoryBean:特殊bean,用于生成另一个特定的bean,例如:ProxyFactoryBean,此工厂用于生产代理对象

@作用域 scope

<bean id="userServiceId" class=" " scope="prototype"></bean>

取值
singleton 单例,默认值
prototype 多例,每执行一次getBean将获得一个实例

@生命周期
初始化和销毁

<bean id=" " class="" init-method="初始化方法名称" destroy-method="销毁的方法名称"></bean>
public class UserServiceImpl implements UserService{
   public void myInit(){
    System.out.println("初始化");
   }
   public void myDestroy(){
    System.out.println("销毁");
   }
  }

备注:1:容器必须close,销毁方法执行 , applicationContext.close();
2:必须是单例的

@BeanPostProcessor后处理Bean
spring提供一种机制,只要实现此接口BeanPostProcessor,并将实现类提供给
spring容器,spring容器将自动执行,在初始化方法前执行before(),z
在初始化后执行after(). 配置,生成代理对象

关键代码:

 return Proxy.newProxyInstance(
    MyBeanPostProcessor.class.getClassLoader(),
    bean.getClass().getInterfaces(),
    new InvocationHandler(){
     @Override
     public Object invoke(Object proxy,Method method,Object[] args)
      throws Throwable{
      System.out.println("-----开启事务");

      //执行目标方法
      Object obj = method.invoke(bean,args);

      System.out.println("------提交事务");
      return obj;
      }});
   }
}

配置文件

<bean class="com.shikun.lifecycle.MyBeanPostProcessor"></bean>

MyBeanPostProcessor后处理bean作用某一个目标类,通过beanName进行控制作用一个

@属性依赖注入

手动装配:一般进行配置信息都采用手动
         基于xml装配:构造方法,setter方法,基于注解装配
自动装配:Struts和spring整合可以自动装配
         byType :按类型装配 byName :按名称装配  constructor:构造装配
auto :不确定装配

1:构造方法注入:

<constructor-arg name=" " value=" " ref=" ">

name:参数的名称 value:设置普通数据 ref:引用数据,一般是另一个bean id值
2:setter方法注入

<property name=""ref="另一个bean"></property>

3:p命名空间

<bean
  p:属性名="普通值" p:属性名-ref="引用值">
</bean>

4:SpEL
对property进行统一编程,所有的内容都是用value

<property name="" value="#{表达式}">

{beanId} :另一个bean引用
{beanId.propName} :操作数据
{beanId.toString()} :执行方法
{T(类).字段|方法} :静态方法或字段

<bean id="customerId" class="">
     <property name="cname" value="#{cutomerId.cname?.toUpperCase()}:></property>
     <property name="pi" value="#{T(java.lang.Math).PI}></property>
</bean>

5:集合注入

集合的注入都是给<、property>添加子标签
数组:<array> List:<list> Set:<set> Map:<map>,map存放k/v键值对,使用<entry>描述
properties:<props> <prop key=""></prop>

普通数据:<value>  引用数据:<ref>
<bean id="collDataId" class="com.itheima.f_xml.e_coll.CollData" >
        <property name="arrayData">
            <array>
                <value>DS</value>
                <value>DZD</value>
                <value>屌丝</value>
                <value>屌中屌</value>
            </array>
        </property>

        <property name="listData">
            <list>
                <value>于禁</value>
                <value>高富帅</value>
                <value>张子凡</value>
                <value>曾小贤</value>
            </list>
        </property>

        <property name="setData">
            <set>
                <value></value>
                <value></value>
                <value></value>
            </set>
        </property>

        <property name="mapData">
            <map>
                <entry key="jack" value="杰克"></entry>
                <entry>
                    <key><value>rose</value></key>
                    <value>肉丝</value>
                </entry>
            </map>
        </property>

        <property name="propsData">
            <props>
                <prop key="高富帅"></prop>
                <prop key="白富美"></prop>
                <prop key="男屌丝"></prop>
            </props>
        </property>
    </bean>

6:装配Bean基于注解

注解:就是一个类,使用@注解名称
1@Component取代<bean class="">
   @Component("id") 取代<bean id="" class="">
2:web开发,提供三个注解取代<bean class="">
   @Repository:dao层
   @Service:service层
   @Controler:web层
3:依赖注入,给私有字段设置,也可以给setter方法设置
   普通值:@Value("")
   引用值:方法1:按照类型注入
           @Autowired
       方法2:按照名称注入
       @Autowired
       @Qualifier("名称")
       方法3:按照名称注入
       @Resource("名称")
4:生命周期
 初始化:@PostConstruct
 销毁:@preDestroy
5:作用域
 @Scope("prototype")多例

@注解

 1:扫描含有注解的类:<context:component-scan base-package="..">
                      <context:annotation-config>
              一般两个注解不一起使用
              注解1:扫描含有注解类
              注解2:只在xml和注解混和使用时,使注入注解生效
 2:常用的注解
    @Component 组件,任意bean
    WEB 
       @Controler web层
       @Service service层
       @Repository dao层

       注入 字段或setter方法
       普通值:@value
       引用值
         类型:@Autowired
     名称1@Autowired @Qualifier("名称")
     名称2@Resource("名称")
    作用域:@Scope("prototype")
    生命周期
      初始化:@PostConstruct
      销毁方法: @PreDestroy

@AOP

1:AOP(面向切面编程):采用横向抽取机制,取代了传统纵向继承体系重复性代码
2:实现原理:aop底层采用代理机制进行实现
            接口+实现类:spring采用jdk的动态代理proxy
        实现类:spring采用cglib字节码增强
3:AOP术语:target:目标类
            Joinpoint:连接点是指那些可能被拦截的方法
        PointCut:切入点:已经被增强的连接点
        advice:通知/增强,增强代码
        Weaving:织入,是指把增强advice应用到目标对象target来
                 创建新的代理对象proxy的过程
        proxy:代理类
        Aspect:切面,是切入点pointcut和通知advice的结合
               一个线是一个特殊的面
           一个切入点个一个通知,组成一个特殊的面

@jdk动态代理
proxy.newProxyInstance:
参数1:loader,类加载器,动态代理类,运行时创建
任何类都需要类加载器将其加载到内存
参数2:class[] interfaces 代理类需要实现的所有接口
参数3:InvocationHandler 处理类,接口,必须进行实现类
一般采用匿名内部类,提供invoke方法,代理类的每一个方法
执行时都将调用一航次invoke
参数1:Object proxy:代理对象
参数2:Method method :代理对象当前执行的方法的描述对象
参数3:Object[] args:方法实际参数

UserService proxService=(UserService)Proxy.newProxyInstance(
                MyBeanFactory.class.getClassLoader(),
        userService.getClass().getInerfaces(),
        new  InvocationHandler(){
        public Object invoke(Object proxy,Method method,
         Object[] args) throws Throwable{

         Object obj = method.invoke();

         }
          });
    return proxService;
}

@CGLIB字节码增强
导入jar包:
核心:hibernate-distribution-3.6.10.Final\lib\bytecode\cglib\cglib-2.2jar
依赖:struts-2.3.15.3\apps\strurs2-blank\WEB-INF\lib\asm-3.3.jar

  //核心类
   Enhancer enhancer = new Enhancer();
   //确定父类
   enhancer.setSuperclass();
   //设置回调函数,MethodInterceptor接口 等效jdk InvocationHandler接口
     intercept() 等效jdk invoke()
     参数4 :methodProxy 方法的代码
    enhancer.setCallback(new MethodInterceptor(){
        public Object intercept(Object proxy,Method method,Object[] args,
     MethodProxy methodProxy) throws Throwable{

     Object obj = method.invoke(userService,args);
     //执行代理类的父类,执行目标类
     methodProxy.invokeSuper(proxy,args);

        }
      });
      //创建代理
      UserServiceImpl proxService =(UserServiceImpl)enhancer.create();
      return proxService();
     }

@AOP联盟通知类型
spring按照通知Advice在目标类方法的连接点位置

 前置通知 org.springframework.aop.MethodBeforeAdvice
         在目标方法执行前实施增强
  后置通知 org.springframework.aop.AfterRetuningAdvice
         在目标方法执行后实施增强
  环绕通知 org.aopalliance.intercept.MethidInterceptor
          在目标方法执行前后实施增强
  异常抛出通知 org.springframework.aop.ThrowsAdvice
         在方法抛出异常后实施增强
   引介通知 org.springframework.aop.IntroductionInterceptor
          在目标类中添加一个新的方法和属性

@spring编写代理:半自动

1:切面类:切面类中确定通知,需要实现不同接口,接口就是规范
             采用环绕通知 :实现 MethodInterceptor 
2:spring配置
    创建代理类:使用工厂bean FactoryBean,底层调用getObject(),返回特殊bean
    ProxyFactoryBean:用于创建代理工厂bean,
     interfaces:确定接口类
     target:确定目标类
     interceptorNames:通知 切面类的名称,类型String[] 
     optimize:强制使用cglib:<property name="optimize" value="true"></property>
     底层机制
         如果目标有接口,采用jdk动态代理
     如果没有接口,采用cglib字节码增强
     如果声明optimize =TRUE ,无论是否有接口,都采用cglib
     <bean id="proxyServiceId" class="org.springframework.aop.framework.ProxyFactoryBean">
         <property name="interfaces" value="com.shikun.factory_bean.UserService"></property>
         <property name="target" ref="userServiceId"></property>
     <property name="interceptorNames" value="myAsoectId"></property>
     </bean>

@spring aop编程 :全自动

 1:spring 配置
   aop编程:使用<aop:config>进行配置
           proxy-target-class="true"声明使用cglib代理
       <aop:pointcut>:切入点,从目标对象获得具体方法
       <aop:advisor>:特殊的切面,只有一个通知和一个切入点
       切入点表达式:execution(*com.shikun.spring_aop.*.*(..))
       选择方法               返回值任意 包 类名任意 方法名任意  参数任意
  <aop:config proxy-target-class="true">
       <aop:pointcut expression="execution(*com.shikun.spring_aop.*.*(..))"id="myPointCut"/>
       <aop:advisor advice-ref="myAspectId" pointcut-ref="myPointCut"/>
  </aop:config>

@ApsectJ

 1:ApectJ是一个基于Java语言的AOP框架
 2:通知类型:
     before:前置通知:在方法执行前执行,如果通知抛出异常,阻止方法运行
     afterReturning:后置通知:方法正常返回后执行
     around:环绕通知:方法执行前后分别执行,可以阻止方法的执行,必须手动执行目标方法
     afterThrowing:抛出异常通知,方法抛出异常后执行
     after:最终通知,方法执行完毕后执行,无论方法中是否出现异常
 3:基于xml
      spring配置
      <aop:aspect>将切面类,声明切面,从而获得通知,ref:切面类应用
      <aop:pointcut>声明一个切入点,所有的通知都可以使用,expressiong切入点表达式
      <aop:config>
         <aop:aspect ref="myAspectId">
     <aop:pointcut expression="execution(*com.shikun.aspect.xml.UserServiceImpl.*(..))" id="myPointCut"/>
     <aop:after method="myAfter" pointcut-ref="myPointCut"/>
     </aop:aspect>
      </aop:config>
4:基于注解
   1:扫描注解类:
     <context:component-scan base-package="com.shikun.aspect.anno"></context:component-scan>
   2:替换aop
     必须进行aspectj自动代理
     <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
   3:aop注解总结
     @Aspect:声明切面,修饰切面类,从而获得通知
     @Before:前置
     @AfterReturning:后置
     @Around:环绕
     @AfterThrowing:抛出异常
     @After:最终
     @PointCut:修饰方法

@JdbcTemplate

 1:spring提供用于操作JDBC工具类
 2:配置
    <bean id="jdbcTemplateId" class="org.springframework.jdbc.core.JdbcTemplate">
       <property name="dataSource" ref="dataSourceId"></property>   
    </bean>
 3:使用JdbcDaoSupport
     dao继承JdbcDaoSupport,之后只需要注入数据源,底层将自动创建模板
     <bean id="userDaoId" class="com.shikun.jdbcdaosupport.userDao">
       <property name="dataSource" ref="dataSourceId"></property>
     </bean>
 4:properties文件
   1:jdbc:driverClass=com.mysql.jdbc.Driver
      jdbc.jdbcUrl=jdbc:mysql://localhost:3306/spring
      jdbc.user=root
      jdbc.password=123
    2:spring配置
     加载配置:classpath:前缀表示src下,在配置文件之后通过${key}获得内容
     <context:property-placeholder location="classpath:com/shikun/properties/jdbcInfo.properties/>
     创建数据源 c3p0
     <bean id="dataSourceId" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driverClass}"></property>
        <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
    <property name="user" value="${jdbc.user}"></property>
    <property name="password" value="${jdbc.pasword}"></property>
     </bean>

@事务管理

1:事务:一组业务操作ABCD,要么全部成功,要么全部不成功
2:特性:ACID  原子性:整体;一致性:完成; 隔离性:并发; 持久性:结果;
3:隔离问题:
      脏读:一个事务读到另一个事务没有提交的数据
      不可重复读:一个事务读到的另一个已提交的数据
      虚读(幻读):一个事物读到另一个事务已提交的数据
4:隔离级别:
   read uncommitted:读未提交
   read committed  :读已提交
   repeatable read :可重复读
   serializable:串行化
5:事务操作:1setAutoCommit 2:mysql事务操作:Savepoint
6:三个顶尖接口:
    PlatformTeansactionManager:平台事务管理器,spring要管理事务,必须使用
                        事务管理器,进行时往往配置时,必须配置事务
    TransactionDefinition:事务详情(事务定义,事无属性),spring用于却动事务具体
                         详情,例如:隔离级别,是否只读等
    TransactionStatus:事务状态,spring用于记录当前事务运行状态。例如:是否有保存点

@PlatformTransactionManager:事务管理器

1:常见的事务管理器
   DataSourceTransactionManager,jdbc开发室事务管理器,采用JdbcTemplate
   HibernateTransactionManager,hibernate开发时事务管理器,整合hibernate
2:api详解
   TransactionStatus getTransaction(TransactionDefinition definition),事务管理器,通过
          “事务详情”,获得“事务状态”,从而管理事务
   void commit(TransactionStatus status) 根据状态提交
   void rollback(TransactionStatus status) 根据状态回滚

   TransactionStatus:
      isNewTransaction(): 是否是新的事务
      hasSavepoint(): 是否有保存点
      setRollbackOnly():设置回滚
      isRollbackOnly():是否回滚
      flush():刷星
      isCompleted():是否完成

@TransactionDefinition:

1:传播行为:在两个业务之间如何共享事务
   PROPAGATION_REQUIRED,required,必须【默认值】,支持当前事务
       A如果有事务,B将使用该事务
       如果A没有事务,B将创建一个新的事务
   PROPAGATION_SUPPORTS,supports,支持
       支持当前事务,A如果有事务,B将使用该事务
       如果A没有事务,B将以非事务执行
   PROPAGATION_MANDATORY,mandatory ,强制
        支持当前事务,A如果有事务,B将使用该事务
        如果A没有事务,B将抛出异常

@整合Junit

1:Junit通知spring加载配置文件
2:让spring容器自动进行注入
@RunWith(SpringJunit4ClassRunner.class)
@ContextConfiguration(locations="classpath:application.xml")
public class TestApp{
    @Autowired //与Junit整合,不需要在spring xml 配置扫描
    private AccountService accountService;

    @Test{
    public void demo1(){
      accountService.transfer("jack","rose",1000);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值