Spring基础内容一

1.Spring是什么?


       Spring就是用来解决对象的创建和对象之间的依赖关系的 这样一门技术


    Spring能干什么?

        1>:创建对象
        2>:依赖关系
        3>:为service提供事务
        4>:整合我们的传统开发框架

 

2.事务:

    1>:粗粒度事务

         只能够对方法进行添加事务 这种称为粗粒度事务(Spring的事务只能够是粗粒度的事务

          以后我们在给访问数据库添加事务的时候是不会将事务写到dao层上的,  因为一个动作是否完成取决于业务逻辑是否完成 ,所以事物都是添加在service上的

   2>:细粒度事务

         就是一个事务能够对我们的程序的某几行提供的事务

   3>:事务的分类

      1>:本地事务

       就是只是对一个数据库添加的事务,   我们目前学习的都叫本地的事物

      2>:全局事务

       举例:银行转账 --中国银行给建设银行转钱 。  这个是两个不同的数据库 ,要同时保证在这两 个表中的操作能够顺利的进行,就必须要使用全局事务

3.Spring的模块图(7个

 

1.Spring AOP模块

     AOP:面向切面的编程

              就是将重复代码抽取出来形成切面类 ,然后当我们程序运行的时候,通过 动态代理或者cglib代理来完成代码的自动植入 的这样一个编程思想 就叫做面向切面的编程

2.Spring ORM模块

      主要是提供了对Hibernate/MyBatis/JDO其他ORM框架整合的支持(对象关系映射)

3.Spring DAO模块

     这个模块实际上是 Spring提供的一个dao层的解决方案(dbutils这种)


4.Spring WEB模块

     这个是Spring提供的对web的支持


5.Spring Context模块

      Spring提供的一个对上下文的支持


6.Spring WEB MVC模块

      这个模块实际上就是传说中的 Spring MVC


7.Spring Core模块


      在我们的Spring中提供了两个思想:  IOC  /  DI

   

        IOC----->表示的是控制反转(inversion  of  control)

        DI ----->依赖注入 (dependcy  injecte)

     反转的是什么?

         1>:以前我们在使用MVC模式来进行开发的时候 service对象是谁创建的?dao对象是谁创建的? 以前我们要使用这个任意类的对象 --->自己通过程序去new一个

         2>:学习了IOC之后那么以后我们的对象的创建就不是我们去完成了,而是由Spring的IOC容器去完成

               那么反转的是什么? 反转的是创建对象的这个权利-----------以前我们自己创建,现在Spring的IOC容器去给我们创建;

               具体控制的是什么? 控制的是创建对象。

 


       依赖注入:注入的是什么?

        依赖表示的是什么意思?谁依赖谁?

        谁依赖谁? 最经典的:controll依赖于service ,service依赖于dao

        依赖注入? 注入的是什么? 注入的是 对象 还有 普通的资源(字符串/boolean/int/float/double)

        控制反转和依赖注入的核心功能包就是:Spring core模块完成的功能

 

4.使用Spring编写一个HelloWorld程序

      1>: 编写程序的第一步:百度下载jar包   spring-framework-4.3.7.RELEASE-dist.jar

      2>:在工程中导入这个包

         commons-logging-1.1.3.jar --->依赖包 日志相关包,是用来辅助运行的

         spring-beans-4.3.7.RELEASE.jar --->实体生成对象的包

         spring-context-4.3.7.RELEASE.jar --->上下文相关包

         spring-core-4.3.7.RELEASE.jar --->核心功能包

         spring-expression-4.3.7.RELEASE.jar --->表达式相关的包


      3>:在我们的src目录下 新建一个文件这个文件的名字是 ApplicationContext.xml这个文件(名字呢实际上是可以随便写)/bean.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"
xmlns:p="http://www.springframework.org/schema/p"
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">
<!--自动生成对象-->
<bean id="user_01" class="com.qf.helloword.User"></bean>

</beans>

 

      4>:配置我们约束

         在我们的下载包里面去找spring的配置文件 打开htmlsingle -->xmlns:p 找个长的 copy过来将bean中的所有的东西删除

      5>:使用API获取这个对象

        第一种模式

public void test() throws Exception {

//有两种模式来获取这个JAVA对象	
//第一种 通过工厂模式来获取JAVA对象
//框架默认的路径就在src下
ClassPathResource resource=new ClassPathResource("bean.xml");
//获取这个工厂
XmlBeanFactory factory=new XmlBeanFactory(resource);
//第三步:获取这个JAVA对象
User user=(User) factory.getBean("user_01");
System.out.println(user);
}

       第二种模式

public void test2() throws Exception {	
ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
//第三步:获取这个JAVA对象
User user=(User) context.getBean("user_01");
System.out.println(user);
}

5.Spring的IOC/DI配置文件

   现在这个对象默认是没有构造函数/没有说明到底是单例的与否....

     1>:默认情况下 生成的JAVA对象是单例的

        配置

       自动生成对象:
       scope="prototype":这个就表示的是多例
       scope="singleton":这个表示的是单例
       lazy-init:表示的是是否延迟创建对象 ,这个只是对单例有效  ,如果不延迟创建那么在web工程中启动工程就会自动创建 ,如果延迟那么表示的是使用的时候才创建对象
        destroy-method="destoryBobo":销毁方法

       init-method="initBobo":初始化方法


       <bean id="user_01" class="com.qf.helloword.User" scope="singleton" lazy-init="false" init-method="initBobo" destroy-method="destoryBobo"></bean>


        假设我想给我们的对象赋值 怎么办?

       调用有参数的构造器

<bean id="user_01" class="com.qf.helloword.User">
<!--这个表示调用的是有多个参数的构造器
index:表示的是参数的下标 value代表的是这个值--> <!-- <constructor-arg index="0" value="中国"></constructor-arg> <constructor-arg index="1" value="美国"></constructor-arg> --> <!-- <constructor-arg name="userName" value="西瓜瓜"></constructor-arg> <constructor-arg name="userPassword" value="123"></constructor-arg> --> </bean>


        下面引用字符串:

<!--假设我要在容器中放入 字符串的对象可不可以直接赋值呢?-->

<bean id="userName" class="java.lang.String">
<constructor-arg index="0" value="我是名字"></constructor-arg>
</bean>

<bean id="userPassword" class="java.lang.String">
<constructor-arg index="0" value="我是密码"></constructor-arg>
</bean>

<bean id="user_02" class="com.qf.helloword.User">
<constructor-arg index="0" ref="userName"></constructor-arg>
<constructor-arg index="1" ref="userPassword"></constructor-arg>
</bean>

         工厂的模式来创建对象

<!--静态的方法生成我们的对象-->

<!--非静态的方法来生成对象-->
<bean id="factory" class="com.qf.helloword.UserFactory"></bean>
<!--省传入那个工厂里面指定方法的对象-->
<bean id="getNoStaticUser" factory-bean="factory" factory-method="getUserByNOStaticFacory"></bean>


<!--通过静态的方法来生成对象-->
<bean id="getStaticUser" class="com.qf.helloword.UserFactory" factory-method="getUserByStaticFacory"></bean>

 

接下来我们研究下获取对象的API

ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("bean.xml");
//第三步:获取这个JAVA对象
//如果使用了类型来找这个对象的话那么 在IOC容器里面就只能有一个类型的对象才能找到
//User user=(User) context.getBean(User.class);

//通过名字来找 最稳定的
//	User user=(User) context.getBean("user_01");


//System.out.println(user);


注意:使用Spring的时候 默认调用的是无参数的构造参数

 

  

DI的配置

set 方法进行注入

1>:在需要对象的地方申明我们的类的成员变量

//Set注入的第一步:申明成员变量
private UserDao userDao=null;
//第二步:为成员变量生成set方法
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
//第三步:在我们的bean.xml中进行如下配置


<!--配置dao-->
<bean id="userDao" class="com.qf.di.UserDao"></bean>

<!--配置Service-->
<bean id="userService" class="com.qf.di.UserService">
<!--ref表示要引用我们ioc容器里面的资源-->
<property name="userDao" ref="userDao"></property>
</bean>

  

p标签进行注入
1>:在需要对象的地方申明我们的类的成员变量

//Set注入的第一步:申明成员变量
private UserDao userDao=null;
//第二步:为成员变量生成set方法
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}

<!--p标签注入-->
<bean id="userService" class="com.qf.di.UserService" p:userDao-ref="userDao"></bean>

内部bean的形式进行注入(基本不用)

<!--内部bean-->

<bean id="userService" class="com.qf.di.UserService">
<property name="userDao">
<bean class="com.qf.di.UserDao"></bean>
</property>
</bean>


自动装配

<!--自动装配-->
<bean id="userDao" class="com.qf.di.UserDao"></bean>
<!--name是通过名字找-->
<!-- <bean id="userService" class="com.qf.di.UserService" autowire="byName"></bean> -->
<!--通过类型找 那么在IOC的 容器中只能有一个对象 有多个的话那么会报错-->
<bean id="userService" class="com.qf.di.UserService" autowire="byType"></bean>

还可以设置全局的自动装配


注解模式的使用

1>:配置扫描器

<context:component-scan base-package="com.qf.anotation"></context:component-scan>

2>将对象放置到IOC容器呢?

@Component @Service @Repository

3>:注对象

@Resource @Autowired

 

注意: 在业务逻辑层推荐使用 @Service

              在dao层推荐使用 @Repository

 

2017-09-13  01:25:06

 

 6.注解的一些详解

 

    1>.spring注解


         @Component("user")

         相当于配置文件里的  :  <bean name="user" class="com.my.bean.User" /> -------把user对象放到容器中


     以下三个注解和@Component("user")相同作用,只是为了体现是哪个层的对象

 

          @Controller("user") // web层or控制层
        @Service("user") // service层
        @Repository("user")// dao层

      -----User实体类  

          public class User {
                   private String name;

                    @Value("18") //注入值,还可以通过在setAge上面写这个注解来注入值
                   private Integer age;

                    @Autowired //自动装配,下面属性为对象,根据类型来检测容器当中所有符合这个属性类型的对象,所以在Car的实体类里要加上                     @Component("car")把Car放入容器中
                    private Car car;//car实体类

       注如果匹配多个类型一致的对象.将无法选择具体注入哪一个对象.即有多个car对象

 

       1).@Autowired //自动装配,
          @Qualifier("car2")//使用Qualifier注解告诉spring容器自动装配哪个名称的对象
          private Car car;

       2).@Resource(name="car")//手动注入,指定注入哪个名称的对象
          private Car car;

 

    2>.其他注解

           Service层

                  @Service     -------默认情况下是将 UserSevice的对象放到 IOC容器里面去 ,默认的名字叫小写userService 
                  @Service(value="userService") -----代表的是我们下面这个类放到IOC容器里面的时候的名字
                  @Scope(value="singleton")------设置这个类的生成模式 是单例的 还是多例的 

                  @Lazy(value=false):--------这个表示的是是否默认延迟生成对象, 这个只是对单例有

 

                 @Repository:--将生成对象放到IOC的容器里面(用法一样)
                 @Component:--这个呢也是生成对象放到IOC容器里面(用法一样)
                 @Resource:---表示的是注入对象(必须在我们的IOC容器里面有这个对象才能进行注入)

 

这儿还未完,代码详解----************************************

 

7.AOP编程

          1>. 什么是AOP编程? 

          AOP编程叫做面向切面的编程,------就是我们在开发中 ,可以将重复的代码抽取出来 形成一个类 ,当我们的程序在运行的时候通过代理的     方式,动态的将我们公共地方的代码可以植入进去进行运行, 这个思想 就叫做 面向切面的编程

        抽取出来的这个公共的类我们以前要么叫基类 ,要么做成一个帮助类utils类;

        而现在抽取出来的这个类 在面向切面编程中叫做 切面类


        代码被植入的地方称为切入点


        描述代码植入的地点的表达式 就称为 切入点表达式

 



        2>. AOP面向切面编程思想:
                过滤器拦截器动态代理   都可以体现AOP思想
                spring aop开发:
                spring封装了动态代理代码,通过配置的形式,我们就不需要手写动态代理代码(被代理对象必须实现接口),还封装了cglib代理             (不需要接口),所以封装了这两个类就可以对任何类进行代理增强。

 

       3>. AOP切入点表达式:             

              com.my.service.UserServiceImpl.save()   //  返回值任意类型,匹配得是com.my.service包下的UserServiceImpl类的空参save方法
              com.my.service.UserServiceImpl.*()    //   *()  所有空参方法
              com.my.service.*ServiceImpl.*(..)   //  *ServiceImpl.*(..)表示匹配所有以ServiceImpl结尾的类并且参数不要求的所有方法
              com.my.service..*ServiceImpl.*(..)   //  两点表示service包的子包也考虑在内

         4>.传统的AOP

 

 1 @Service//注解,告诉我们属于业务层
 2 public class UserService {
 3     @Autowired //自动装配
 4     private Aop aop=null;
 5 
 6         @Autowired
 7     private UserDao userDao=null; 
 8 
 9     public void regsiter(){
10         aop.startTransaction();
11         userDao.save();
12         aop.endTransaction();
13     }
14 }

 

           5>.cglib下实现代理

 

 

 1 @Component
 2 public class UserServiceProxy implements MethodInterceptor{
 3     @Autowired
 4     private UserService userService=null;
 5     @Autowired
 6     private Aop aop=null;
 7     
 8     /**
 9      * 生成对象
10      * @return
11      */
12     public Object getObject(){
13         Enhancer enhancer=new Enhancer();
14         enhancer.setSuperclass(userService.getClass());
15         enhancer.setCallback(this);
16         return enhancer.create();
17     }
18     @Override
19     public Object intercept(Object object, Method method, Object[] args,
20             MethodProxy arg3) throws Throwable {
21             //首先获取的是方法体的名字
22             String methodName=method.getName();
23             Object returnValue=null;
24             
25             if("regsiter".equals(methodName)){  //表示当前执行的是regsiter方法
26                 aop.startTransaction();
27                 //执行这个方法
28                 returnValue=method.invoke(userService,args);
29                 //植入我们的关闭事务的方法
30                 aop.endTransaction();
31             }else{
32                 
33                 returnValue=method.invoke(userService, args);
34             }
35             return returnValue;
36     }
37 
38 }

 

         6>.动态实现AOP编程

 1  @Test
 2     public void test() throws Exception {
 3         //生成一个动态代理的对象出来
 4         ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("com/qf/aop_03/bean.xml");
 5         final Aop aop=context.getBean(Aop.class);
 6         final UserService service=context.getBean(UserService.class);
 7         
 8         IUserService service2=(IUserService) Proxy.newProxyInstance(
 9                 UserService.class.getClassLoader(),
10                 UserService.class.getInterfaces(),
11                 new InvocationHandler() {
12                     /**
13                      * 方法执行的时候的中断的方法
14                      */
15                     @Override
16                     public Object invoke(Object proxy, Method method, Object[] args)
17                             throws Throwable {
18                         //获取请求方法的名字
19                         String methodName=method.getName();
20                         Object returnValue=null;
21                         if("regsiter".equals(methodName)){
22                             //说明目前访问的是register方法
23                             aop.startTransaction();
24                             returnValue=method.invoke(service, args);
25                             aop.endTransaction();
26                         }else{
27                             returnValue=method.invoke(service, args);
28                         }
29                         
30                         return returnValue;
31                     }
32                 });
33         
34         service2.regsiter();
35     }

          7>.注解下的AOP

 

                  @Component //这个表示的是当前这个类放到我们的ioc容器中去
                  @Scope("singleton") //当前这个类生成对象的时候 使用的单例
                  @Aspect //表示当前的这个类是一个切面类

       例:

                 就需要告诉Spring 我们要将程序放到哪里去
             (execution (   :  表示的是语法规则
                    *    :    表示的是返回值类型可以是任意的类型
                     com.my.aop.anotation.UserService.*  :   后面的这个*表示的是所有的方法
                    (..)  :   这个表示的是参数的数据类型

                完整组合起来就是:execution (  *  com.qf.aop.anotation.UserService.*  (..)  )

                     切入点表达式
                 @Pointcut(value="(execution (* com.qf.aop.anotation.UserService.*(..)))")
                  public void pt(){

                   }

 


                @Before("pt()"):表示的是在执行切入点方法之前调用下面的方法

 

                @After("pt()"):表示的是执行切入点表达式方法之后要执行的方法

 

                @AfterThrowing("pt()"):出现异常的时候执行的方法

 

                @AfterReturning("pt()"):返回值的时候动态植入的方法

 

                @Around("pt()"):环绕的时候执行的方法

 

 

 


            8>.配置模式下的AOP

 

 1 <beans xmlns="http://www.springframework.org/schema/beans"
 2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
 3 xmlns:context="http://www.springframework.org/schema/context"
 4 xmlns:aop="http://www.springframework.org/schema/aop"
 5 xsi:schemaLocation="
 6 http://www.springframework.org/schema/beans
 7 http://www.springframework.org/schema/beans/spring-beans.xsd
 8 http://www.springframework.org/schema/context
 9 http://www.springframework.org/schema/context/spring-context.xsd
10 http://www.springframework.org/schema/aop
11 http://www.springframework.org/schema/aop/spring-aop.xsd">
12 <!--配置dao-->
13 <bean id="userDao" class="com.qf.aop.config.UserDao"></bean>
14 
15 <!--配置咋们的Service-->
16 <bean id="userService" class="com.qf.aop.config.UserService" p:userDao-ref="userDao"></bean>
17 
18 <!--配置我们的aop对象-->
19 <bean id="aop" class="com.qf.aop.config.Aop"></bean>
20 
21 <!--下面就开始配置我们的aop了-->
22 <aop:config>
23 <!--配置的是切入点表达式-->
24 
25 
26 <aop:pointcut expression="(execution (* com.qf.aop.config.UserService.*(..)))" id="pt"/>
27 <aop:aspect ref="aop">
28 <!--环绕的时候执行-->
29 <aop:around method="returnAround" pointcut-ref="pt"/>
30 <!--在执行某一个方法之前来执行-->
31 <aop:before method="startTransaction" pointcut-ref="pt"/>
32 <!--在某个方法之后植入指定代码-->
33 <aop:after method="endTransaction" pointcut-ref="pt"/>
34 <!--出现异常-->
35 <aop:after-throwing method="throwException" pointcut-ref="pt"/>
36 <!--返回结果的时候植入代码-->
37 <aop:after-returning method="returnAfter" pointcut-ref="pt"/>
38 </aop:aspect>
39 </aop:config>
40 </beans>

 

 

 

8.Spring提供的JdbcTemplate来实现数据库的相关操作

 

     1.Spring中配置我们的C3p0连接池

 

           1>:要使用Spring提供的 Jdbctemplate来完成数据库操作的话 首先导入包

 

                           Spring对Jdbctemplate支持的包

                           spring-jdbc-4.3.7.RELEASE.jar jdbc支持包

 

                           spring-tx-4.3.7.RELEASE.jar 事务相关的包

                           c3p0-0.9.1.2.jar C3p0连接池的相关包

 

                           mysql-connector-java-5.1.7-bin.jar 驱动程序的相关包

 

            2>:在配置文件中进行如下的配置

 

 1 <!--要使用C3p0的话首先配置数据源-->
 2 <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
 3 <property name="acquireIncrement" value="2"></property>
 4 <property name="maxPoolSize" value="100"></property>
 5 <property name="initialPoolSize" value="2"></property>
 6 <property name="minPoolSize" value="2"></property>
 7 <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
 8 <property name="jdbcUrl" value="jdbc:mysql:///Day1704_Spring"></property>
 9 <property name="user" value="root"></property>
10 <property name="password" value="root"></property>
11 </bean>
12 
13 <!--配置我们的Spring中核心的访问数据库的这个类-->
14 <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
15 <property name="dataSource" ref="dataSource"></property>
16 </bean>
17 
18 <!--配置我们的userDao对象-->
19 <bean id="userDao" class="com.qf.jdbc.UserDao" p:jdbcTemplate-ref="jdbcTemplate"></bean>

              3>:编写增删该查的方法

 

 1 public class UserDao {
 2 
 3 
 4 private JdbcTemplate jdbcTemplate=null; //这个类是Spring提供的访问数据库的
 5 public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
 6 this.jdbcTemplate = jdbcTemplate;
 7 }
 8 /**
 9 * 添加数据    
10 * @param user
11 */
12 public void save(String uName,String uPassword){
13 String sql="insert into t_user(uName,upassword) values(?,?)";
14 jdbcTemplate.update(sql,uName,uPassword);
15 }
16 /**
17 * 删除数据    
18 * @param user
19 */
20 public void delete(int uId){
21 String sql="delete from t_user where uId=?";
22 jdbcTemplate.update(sql,uId);
23 }
24 /**
25 * 更新数据
26 * @param user
27 */
28 public void update(User user){
29 String sql="update t_user set uName=?,uPassword=? where uId=?";
30 jdbcTemplate.update(sql,user.getuName(),user.getuPassword(),user.getuId());
31 }
32 /**
33 * 查询数据
34 * @param user
35 */
36 public List<User> query(){
37 String sql="select * from t_user";
38 List<User> list=jdbcTemplate.query(sql,new RowMapper<User>(){
39 @Override
40 public User mapRow(ResultSet set, int arg1) throws SQLException {
41 
42 int uId=set.getInt("uId");
43 String uName=set.getString("uName");
44 String uPassword=set.getString("uPassword");
45 User user=new User();
46 user.setuId(uId);
47 user.setuName(uName);
48 user.setuPassword(uPassword);
49 return user;
50 }
51 });
52 
53 return list;
54 }

 

 

 

 

posted @ 2017-09-13 01:25  大西瓜猫  阅读(227)  评论(0编辑  收藏  举报