Spring笔记

来源:互联网 发布:log4j2连接数据库 编辑:程序博客网 时间:2024/05/21 22:30
------------------------------------------Spring的IOC,DI--------------------------------------------------------
在idea里开发spring项目时。
需要把log4j.properties文件放到src下。
接着导入spring的jar包。在J2EE开发工具里。
在src下新建一个xml文件。文件进行如下配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans.xsd"
>
    <bean id="success" class="com.fusong.spring.demo1.HelloSpringImp"></bean>
</beans>
2.DI:在容器内的组件可以通过setter方法,可以把该类的属性通过applicationContext配置后。
将该类的值注入。注意通过applicationContext配置时,需要把property放在对应的类的Bean里面
3.ApplicationContext一加载配置文件时就创建了对象
4.ApplicationContext提供了扩展:
①国际化处理   ②事件传递   ③Bean自动装配   ④各种应用层的Context实现
5.Bean的创建方式一般是:<bean id="??" class="??"></bean>
6.bean的其他配置里:
id和name的区别:id遵守XML的约束,而name不用遵守。
****如果Bean标签上没有配置id,那么name可以作为id。
经测试:如果一个bean标签里同时出现id和name。那么getBean都可以获取到。
现在的开发中都是用id。
7.类的作用范围:
 scope属性:
   *singleton:单例的
   *prototype:多例的
开发中主要用这两个
8.在这里我们的applicationContext.xml.每当ApplicationContext创建时都要加载该文件,所有的类
都会被加载,极大浪费资源
9.spring里的后处理Bean,postProcessAfterInitialization很重要
10.依赖的属性DI可以通过①构造器注入   ②setter方法注入
构造器注入使用的<constructor-org>.
setter方法注入:使用<property>
若是想注入我们创建的某个类。需要用ref,它的属性值是该类的id。这时就不能用value了。
ref注入的是复杂属性,value注入的是简单属性
11.名称空间注入属性
xmlns:p="http://www.springframework.org/schema/p"
注入属性时应该这样写:    <bean id="car" class="com.fusong.Demos.Car"  p:name="保时捷"
          p:price="1500000"
    />
12.List集合的注入:
<bean id="demolist" class="com.fusong.Demos.DemoList">
    <property name="list">
        <list>
            <value>**</value>
            <value>**</value>
            <value>**</value>
        </list>
    </property>
这里的list是我们之前在类里定义的属性
Map集合的注入:
<bean id="demolist" class="com.fusong.Demos.DemoList">
    <property name="map">
        <map>
            <entry key="??" value="??"></entry>
            
        </map>
    </property>
13.为了解决配置文件代码量过多,维护难的问题:
①可以选择引入配置文件,引入方法:<import resource="??"></import>
②可以在加载配置文件时引入多个文件:ClassPathXMLApplicationContext("applicationContext.xml","applicationContext2.xml");
用该方法时就不要有标签了
14.使用注解的方式完成属性注入:
 *注解的方式装配Bean
在被注入的类上加@Component();
 配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
">
    <context:annotation-config></context:annotation-config><!--XML与注解混搭的时候用的,纯注解可以不写-->
    <context:component-scan base-package="com.fusong.demo2"></context:component-scan>
</beans>
另外:如果报这样的错误:Line 1 in XML document from class path resource [applicationContext3.xml] is invalid;
那就说明配置文件配错了
  *完成属性注入
 ①要是普通属性,可以使用@Value();
 
Error creating bean with name 'userService': Unsatisfied dependency expressed through field 'person'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
要是报这样的错误,需要在
①ClassPathXmlApplicationContext加person所在的applicationContext.xml文件。
或者②在<context:component-scan base-package里加上person所在的包
***属性的值注入方式有三种:setter,构造器,接口。XML完成Bean的属性装配需用到ApplicationContext。
使用注解可以轻松完成Bean的属性装配。
15.@Repository用于标注数据访问组件,即DAO组件
16.Spring整合Web开发:
servlet每次都要读取配置文件。极大地降低了效率。
①我们可以在init方法里读取文件。但是多个servlet就要有多个init
②将加载的信息内容放到ServletContext中,ServletContext是全局对象。是服务器启动的时候
创建的,在创建ServletContext时就加载文件。,ServletcontextListener用于监听ServletContext
的创建与销毁
在servlet里使用WebApplicationContext。需要加一个spring-web-3.2.0.RELEASE.jar包
在web.xml里配置如下:
<display-name></display-name>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:beans.xml</param-value>
</context-param>
或者还可以这样:
<display-name></display-name>
<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>WEB-INF:bean.xml</param-value>
</context-param>
17.Spring与JUnit的整合,优点:减少代码量,不用自己再去写读取文件的代码。
只需指定要配置的文件,注入类即可。
在@RunWith()里,指定SpringJUnit4ClassRunner.class
在@ContextConfiguration()里,指定locations要加载的文件。
@Autowired为要注入的类自动注入属性
在@Test里直接调用方法即可
---------------------------------------Spring的AOP概述-------------------------------------------
18.AOP,面向切面编程。它采取横向抽取机制,取代了传统纵向继承体系重复性,他可以用来做性能监视,事务
管理,安全检查,缓存.
19.AOP在运行期通过代理方式向目标类植入代码进行增强.AOP底层原理其实是代理机制
 *JDK动态代理(经典代理):对实现了接口的类生成代理
 *CGLib代理机制:对类生成代理,其实生成了一个真实对象的子类。
   *做cglib的开发,可以不用直接引入cglib的包,在Spring的核心中集成了cglib
   *cglib的核心类叫Enhancer。
使用哪个更合适,结论:Spring框架,如果类实现了接口,就使用JDK生成代理对象。若这个类
没有实现接口,就是用CGLib生成代理对象
20.AOP的术语理解:
public class UserDao{
public void add(){}
public void delete(){}
public void update(){}
public void search(){}
}
①Joinpoint:连接点,指的是哪些方法可以被拦截,以上的四个方法都可以被拦截,被增强
②Pointcut:切入点,又称切点。对哪些Joinpoint进行拦截,真正要拦截的方法
③Advice:通知。要增强的代码。就是对代码的增强,方法级别的增强。如可以再代码里加上writelog(),增加功能
④Introduction:引介。一种特殊的增强,类级别的增强。一般不会用到
⑤Target:目标对象。被增强的类对象
⑥weaving:是指把增强应用到目标对象来创建新的代理对象的过程。就是把Advice增强应用到Target上
⑦Aspect:切面。切入点和通知的结合,在add或delete方法上应用增强。add相当于切点,增强相当于advice。
Aspect允许有多个切点和多个通知的组合!!
21.自动代理:
CGLIB,JDK创建的代理与自动代理的区别:
CGLIB,JDK要先创建一个类的对象,通过类的对象获取代理对象。
自动代理基于后处理Bean,在Bean的创建的过程中完成类的增强。生成的Bean就是代理
普通配置,每次写一个类都要为他配置一个代理。这样太麻烦。于是便有了自动代理    
BeanNameAutoProxyCreator  根据Bean名称创建代理
DefaultAdvisorAutoProxyCreator 根据Advisor本身包含的信息创建代理
22.AspectJ:它是一个基于Java语言的AOP框架。
*基于注解的AspectJ  
  *配置使用@AspectJ切面
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!--该句的作用是,开启AspectJ自动代理-->
<aop:aspectj-autoproxy/>
</beans>
   *我们说切面是切点和通知的组合。AspectJ提供的不同的通知类型
   切点即是:execution()函数表达式。
        *execution(* com.fusong.MyAspectJ..*(..)),前面的*表示任意类型,后面的*表示该包和子包下的所有的类
        *execution(* com.fusong.MyAspectJ.UserDao*(..)),匹配UserDao类的所有方法
        *execution(* com.fusong.MyAspectJ.UserDao.delete(..)),只针对该类下的delete方法
   通知即是:@Before,前置通知。@AfterReturning(),可以获得返回值,后置通知。@Around,环绕通知。
@Aspect:作用是把当前类标识为一个切面供容器读取
 @Before:标识一个前置增强方法,相当于BeforeAdvice的功能,相似功能的还有
@AfterReturning:后置增强,相当于AfterReturningAdvice,方法正常退出时执行
 @AfterThrowing:异常抛出增强,相当于ThrowsAdvice
   用的时候,如:@AfterReturning("execution(* com.fusong.AspectJ.UserDao.delete(..))")
   在MyAspectJ切面类里,@Aspect的作用是定义切面
   *定义切点,为了增强某个方法,我们可能会写多个重复的execution()。为了解决这个,我们可以用
   @Pointcut(),来解决。
       @Pointcut("execution(* com.fusong.AspectJ.UserDao.update(..))")
        public  void  update(){}
   *Advisor(注意不是Advice)和Aspect的区别:
       *Advisor:Spring传统意义上的切面,支持一个切点和通知的组合
       *Aspect:可以支持多个切点和多个通知的组合
*基于XML的AspectJ:
------------------------------------------------Spring管理JDBCTemplate---------------------------------------------
23.Spring的JDBCTemplate模板与DButils类似,实际开发中,通过Spring配置文件来配置JdbcTemplate。
配置连接池代码;
 DriverManagerDataSource dataSource=new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/newstart");
        dataSource.setUsername("root");
        dataSource.setPassword("fusong");
使用spring的模板:
 JdbcTemplate template =new JdbcTemplate(dataSource);
        String sql="create table account (IdCard varchar(20) primary key not null,money double DEFAULT '0')";
        template.execute(sql);
24.JdbcTemplate 的CRUD操作:
 *简单查询(查询数字,查询字符串)
---------------------------------------------Spring的事务管理---------------------------------------------------  
25.事务:逻辑上的一组操作,要么全都成功,要么全都失败。
它具有的事务特性:
①原子性:事务不可分割
②一致性:事务执行前后,数据完整性保持一致
③隔离性:一个事务执行的时候,不应该受到其他事务的干扰
④持久性:一旦结束,数据就永久保存到数据库
*如果不考虑隔离性:
   *脏读:一个事务读到另一个事务未提交的数据
   *不可重复读:一个事务读到另一个事务已提交数据(update),导致一个事务多次查询结果不一致
   *虚读:一个事务读到另一个事务已提交数据(insert),导致一个事务多次查询结果不一致
*事务的隔离:
   *未提交读:以上情况都可能发生
   *已提交读:避免脏读,但不可重复读,虚读有可能发生
   *串行的:避免以上所有情况
26.Spring中事务管理
分层开发:事务在业务层(service)
*PlatformTransactionManager:平台事务管理器
  commit(TransactionStatue status)
  getTransaction(TransactionDefinition definition)
  rollback(TransactionStatue status)
*TransactionDefinition:事务定义
  ISOLation_XXX:事务隔离级别
  PROPAGATION_XXX:事务的传播行为(不是JDBC中有的,为了解决实际开发问题)
*TransactionStatus:事务状态
  是否有保存点
  是否有一个新事物
  事务是否已经提交
关系:PlatformTransactionManager通过TransactionDefinition设置事务隔离级别,事务的传播行为
管理事务,管理事务过程中,产生一些事物状态:状态由TransactionStatus记录
27.传播行为为了解决事务中的复杂应用:
 *可能一个业务层调用另一个业务层代码完成一个逻辑操作。两个业务层都有事务操作管理。
service1调用service2。如果service2出现了异常,service1照样能提交。    
总之:传播行为解决事务间调用的问题
28.常用事务的传播行为:
  ①PROPAGATION_REQUIRED
  ②PROPAGATION_REQUIRES_NEW
  ③PROPAGATION_NESTED
29.Spring的事务管理分成两类:
*编程式事务管理
    *手动编写代码完成
①配置事务管理器
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="datasource"/>
</bean>
②注册事务摸板类
<bean id="transactionManagerTemplate" class="org.springframework.transaction.support.TransactionTemplate">
    <property name="transactionManager" ref="transactionManager"/>
</bean>
③在业务层注入摸板类
④在业务层代码上使用模板
手动编码方式缺点:
 *代码量增加,代码有侵入性
*声明式事务管理
    *使用配置完成
我建了一个ServiceDaoProxy,旨在用代理类完成操作。
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-config.xml")
public class ServiceDaoProxy  implements ServiceDao{
    @Autowired
    @Qualifier("accountImp")
    private AccountDao accountDao;
    @Override
    public void transfer(String sender, String getter, Double money) {
        accountDao.transfer1(sender,money);
        //int a=10/0;
        accountDao.transfer2(getter,money);
    }
}
-------------------------------------------------------------------------
配置如下:    
<bean id="serviceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="target" ref="servicedao"/><!--这里是为ServiceDaoImp类做代理-->
        <property name="transactionManager" ref="transactionManager"/>
        <property name="transactionAttributes">
            <props>
                 <!--transfer,里是为servicedao所在类的方法,这里是给它增强-->
                <prop key="transfer">PROPAGATION_REQUIRED</prop>
            </props>
        </property>
    </bean>
缺点:需要为每一个管理事务的类生成代理,需要为每个类配置
----------------------------------------------------------------------------------
测试类如下:
  @Autowired
    @Qualifier("serviceProxy")
    public ServiceDao serviceDao2;
    @Test
    public  void  test2(){
        serviceDao2.transfer("145632587","896541235", (double) 500);
    }
------------------------------------------------------------------------------------
30.prop格式:PROPAGATION,ISOLATION,readOnly,-Exception,+Exception
  *顺序:传播行为,隔离级别,事务是否只读,发生哪些异常可以回滚事务
*以上两种不要记:
31.声明式事务管理:(自动代理,基于切面,重点掌握)
配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
  http://www.springframework.org/schema/tx
       http://www.springframework.org/schema/tx/spring-tx.xsd
       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
----------------------------------------------------------------------------------------------------------
<tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="transfer"/>
        </tx:attributes>
    </tx:advice>
    <aop:config>
        <aop:pointcut id="mypointcut"
                      expression="execution(*  com.fusong.transfer.service.ServiceDao.transfer(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="mypointcut"/>
    </aop:config>
----------------------------------------------------------------------------------------------------------
32.基于注解的声明式事务管理:
<tx:annotation-driven transaction-manager="transactionManager"/>
----------------------------------------------------------------------------------------------------------
@Transactional
public interface ServiceDao {
    public  void  transfer(String sender, String getter, Double money);
}

原创粉丝点击