Spring框架介绍

一、用分层思想实现程序结构优化

(1)这是一个基于SSH框架的网站文件布局

代码结构

(2)以下是一个基于SSH框架的网站流程图

SSH框架流程图

(3)以下是一个基于SSM框架的网站流程图

SSM框架流程图

二、Spring IOC功能详述

1.注解方式实现IOC

使用注解方式之前,在applicationContext.xml里面加上一下配置:

<!-- 自动装配 -->
<context:annotation-config/>
<!-- 指定组件的路径 -->
<context:component-scan base-package="com.juligang.dao.impl,com.juligang.service.impl,com.juligang.action.UserAction"></context:component-scan>

Action层

package com.juligang.action;

import java.io.IOException;
import java.io.PrintWriter;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.struts2.ServletActionContext;

import com.juligang.model.User;
import com.juligang.service.UserService;

public class UserAction {
    User user;
    UserService service;       //调用Service层
    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    public UserService getService() {
        return service;
    }
    @Resource(name="service")       //通过注解方式注入service
    public void setService(UserService service) {
        this.service = service;
    }

    public String addOrUpdate()
    {
        service.add(user);
        return login();
    }

    public String checkExist()
    {
        user=service.check(user);
        HttpServletResponse response=ServletActionContext.getResponse();
        try {
            PrintWriter out=response.getWriter();
            if(null!=user)
            {
                out.print("YES!"+user.getId());
            }
            else
            {
                out.print("NO!"+user.getId());
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    public String login()
    {
        //context只在一次请求时有效
        //ActionContext context=ActionContext.getContext();
        //context.put("USER", user);
        HttpServletRequest request=ServletActionContext.getRequest();
        HttpSession session=request.getSession();
        session.setAttribute("USER", user);
        return "main";
    }

    public String exit()
    {
        HttpServletRequest request=ServletActionContext.getRequest();
        HttpSession session=request.getSession();
        session.setAttribute("USER", null);
        return "main";
    }
}

Service实现层

package com.juligang.service.impl;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

import com.juligang.dao.UserDAO;
import com.juligang.model.User;
import com.juligang.service.UserService;
@Component(value="service")        //通过注解建立一个service实现类,共Action层装配
public class UserServiceImpl implements UserService {
    UserDAO dao;
//  这是构造函数方式注入  
//  public UserServiceImpl(UserDAO dao) {
//      super();
//      this.dao = dao;
//  }

//  这是setter方式注入
    public UserDAO getDao() {
        return dao;
    }
    @Resource(name="sqlDAO")            //通过注解给DAO装配一个实现类
                                       //可以装配sqlDAO,也可装配fileDAO
    public void setDao(UserDAO dao) {
        this.dao = dao;
    }

    @Override
    public void add(User user) {
        // TODO Auto-generated method stub
        dao.save(user);
    }
    @Override
    public User check(User user) {
        // TODO Auto-generated method stub
        return dao.check(user);
    }
}

DAO实现层

(1)MySQL实现层

package com.juligang.dao.impl;

import javax.annotation.Resource;

import org.springframework.orm.hibernate4.HibernateTemplate;
import org.springframework.stereotype.Component;

import com.juligang.dao.UserDAO;
import com.juligang.model.User;

@Component(value="sqlDAO")               //DAO实现类1
public class UserDAOMySqlImpl implements UserDAO {
    HibernateTemplate hibernateTemplate;
    @Resource
    public void setHibernateTemplate(HibernateTemplate hibernateTemplate) {
        this.hibernateTemplate = hibernateTemplate;
    }

    @Override
    public void save(User user) {
        hibernateTemplate.merge(user);
    }

    @Override
    public User check(User user) {
        // TODO Auto-generated method stub
        return hibernateTemplate.findByExample(user).get(0);
    }

}

(2)File实现类

package com.juligang.dao.impl;

import java.io.FileWriter;
import java.io.IOException;

import org.springframework.stereotype.Component;

import com.juligang.dao.UserDAO;
import com.juligang.model.User;

@Component(value="fileDAO")             //DAO实现类2
public class UserDAOFileImpl implements UserDAO {

    @Override
    public void save(User user) {
        // TODO Auto-generated method stub
        FileWriter fw;
        try {
            fw = new FileWriter("e:\\Users.txt",true);
            fw.write(user.getName()+":"+user.getPwd());
            fw.write("\r\n");
            fw.close();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    public User check(User user) {
        // TODO Auto-generated method stub
        return user;

    }
}

注解方式总结:
Action层
@Resource(name=”userService”) //装配对象

Service实现层
@Component(value=”userService”) //初始化一个对象

@Resource(name=”sqlDAO”)

DAO实现层
@Component(value=”sqlDAO”)

@Component(value=”fileDAO”)

注意:如果把Component里面的value和Resource里面的name省略掉,那么默认值为类的第一个字母小写全称

这也是基于分层思想的技术实现

2.XML方式实现IOC
与注解方式实现的效果一样,只是把装配控制权交给了XML配置文件
IoC=控制反转=inverse of control
注解方式控制权在源代码中,通过这种方式,控制权在配置文件中
DI =依赖注入=dependency injection

同样是上面的程序
去掉@Component和@Resource注解,这些定义和装配的任务都放在.xml文件中

<!-- UserDAOFileImpl类实例一个对象filedao,以下类似 --> 
<bean id="fileDAO" class="com.juligang.dao.impl.UserDAOFileImpl"></bean>
<bean id="sqlDAO" class="com.juligang.dao.impl.UserDAOMySqlImpl"></bean>
    <!-- service是Action中的属性,依赖于dao的注入 -->
<bean id="service" class="com.juligang.service.impl.UserServiceImpl">
        <!-- dao是service实现类中的属性,依赖于dao的实现类注入 -->
        <property name="dao" ref="sqlDAO"></property>
    </bean>

不能像注解方式那样一层一层往上装配。

3.Spring IoC的基本原理
inverse of control = 控制反转
dependency injection = 依赖注入

帮我们创建对象,帮我们组织和装配对象

1.自动装配
autowire :byName,byType
(1)默认的装配方式

<bean id="fileDAO" class="com.juligang.dao.impl.UserDAOFileImpl"></bean>
<bean id="sqlDAO" class="com.juligang.dao.impl.UserDAOMySqlImpl"></bean>
<bean id="service" class="com.juligang.service.impl.UserServiceImpl">
    <property name="dao" ref="sqlDAO"></property>
</bean>

(2)自动装配autowire :byName

<bean id="dao" class="com.juligang.dao.impl.UserDAOFileImpl"></bean>
<bean id="service" class="com.juligang.service.impl.UserServiceImpl"  autowire="byName">
</bean>

UserServiceImpl类中有一个属性dao,需要注入,我们设置autowire=”byName”,所以Spring会自动去寻找跟dao名字相同的实现进行装配
由于dao有2个实现类,你要装配哪个,就把那个实例成dao
(3)自动装配autowire :byType

<bean id="fileDAO" class="com.juligang.dao.impl.UserDAOFileImpl"></bean>
<bean id="sqlDAO" class="com.juligang.dao.impl.UserDAOMySqlImpl"></bean>
<bean id="service" class="com.juligang.service.impl.UserServiceImpl autowire="byType"">
</bean>

由于dao的实现类有两个,如果根据Type去自动装配会出问题,如果只有一个实现类,那么与根据Name装配效果一样

default-autowire:byname,byType
它是beans的一个属性,bean的属性autowire类似,不再举例

public class UserServiceImpl implements UserService {
    UserDAO dao;
//  这是构造函数方式注入  
//  public UserServiceImpl(UserDAO dao) {
//      super();
//      this.dao = dao;
//  }

//  这是setter方式注入
    public UserDAO getDao() {
        return dao;
    }
    @Resource(name="sqlDAO")            
    public void setDao(UserDAO dao) {
        this.dao = dao;
    }

被注释的代码采用的就是构造函数方式注入的,不过xml文件的配置也不同,如下:

<bean id="fileDAO" class="com.juligang.dao.impl.UserDAOFileImpl"></bean>
<bean id="sqlDAO" class="com.juligang.dao.impl.UserDAOMySqlImpl"></bean>
<bean id="service" class="com.juligang.service.impl.UserServiceImpl">
    <constructor-arg name="dao" ref="sqlDAO"></constructor-arg >
</bean>

3.不同属性的注入方式,只做了解
简单属性注入:int,String,float
集合属性注入:Map,List,Set

4.bean的单实例与多实例属性

scope = singleton,prototype,request,session,global session
默认是singleton 单例,prototype 原型,模板

比较两个类的区别

class Student
{
   private int age;
   public void setAge(int age)
   {
       this.age=age;
   }
   public void show()
   {
       System.out.println(age);
   }
}

class StudentDAO
{
    public void save(Student student)
    {
       ......
    }
}

Student zhang=new Student();
zhang.setAge(20);

Student lee=new Student();
lee.setAge(18);

这种有参的类,不能是单实例,否则每个实例都一样,会有问题。

5.延时加载
lazy-init 容器加载时不初始化
default-lazy-init

6.初始化方法和销毁方法
init-method 和 destroy-method
在类中写一个初始化方法和一个销毁方法,在bean的属性中加以说明,如果方法初始化或完成时会被调用到。

三、Spring AOP功能详述

  1. AOP基本原理及面向切面编程的实现
    复习动态代理,

作用:可以在现有方法之上添加代码,增加现有程序的功能。

讲好处!

1.将与业务无关的通用功能抽取出来,单独编写,
开发人员可以专注于业务逻辑的编写。
这些通用功能包括日志,权限管理,事务处理,异常处理等。

2.通用功能的增加与删除,可以通过配置文件进行配置。

3.是一种编程方式的革命!

引入AOP:面向切面的编程

AOP=面向切面编程=Aspect Oriented Programming

技术原理:动态代理

之前讲过的OOP
OOP=面向对象编程=Object Oriented Programming

AOP 类似jsp中的filter(过滤器),struts2中的interceptor(拦截器)

注解配置,XML配置

(1)学习在注解方式使用aop

这个功能应该加在哪个类的哪个方法上??是加在方法执行之前,还是之后??

@Before(“execution(public void net.xinqushi.service.impl.save(net.xinqushi.model.User))”)
这里写图片描述
spring中使用了一套面向aop编程的框架,叫做aspectj。

修改spring配置文件applicationContext.xml
添加AOP的命名空间及xml约束文件
xmlns:aop=”http://www.springframework.org/schema/aop”

http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.1.xsd

增加支持注解功能

  1. AOP详解及通过XML配置实现的方法
    Spring AOP 的一些术语

    切面(Aspect)
    要增加什么功能?事务管理,日志管理,权限管理,异常处理

    连接点(Joinpoint)
    哪个类的哪个方法上增加功能?

    通知(Advice)
    加在方法的什么位置?前面?后面?产生异常时?环绕??

    切入点(Pointcut)
    给连接点命名,便于在多处使用。

    目标对象(Target Object)
    被代理对象,自己的功能不够强大,要通过aop加强。

    AOP代理(AOP Proxy)
    功能已经加强的哪个对象

    织入(Weaving)
    把新功能和本身的功能组织在一起执行。

1.joinpoint语法:用一些通配符来定义在哪些类和方法上增加aop功能。

语法:
1).execution(public * *(..))
所有public方法

2).execution(* set*(..))
所有以set作为方法名开头的方法

3).exuection(* com.xzy.service.AccountService.*(..))
com.xzy.service.AccountService类中的所有方法

4).execution(* com.xyz.service..(..))
com.xyz.service包中所有类的所有方法

5).execution(* com.xyz.service...(..))
com.xyz.service包及子包下的所有类的所有方法

2.pointcut:给joinpoint取个名字。
@pointcut(“execution( * com.xzy..(..))”)
public void businessService(){}
这里写图片描述
3.advice

@Before
@AfterReturning
@AfterThrowing
@After(finally)
@Around

4.JoinPoint jp
ProceedingJointPoint pjp
定义了Pointcut之后,很多方法都可以添加此切面,无法区分。所以可以给方法传入参数,切面执行时可以带上方法本身特有的属性加以与其他方法区分。
这里写图片描述
5.xml配置AOP

<bean id="log" class="com.juligang.aop.Log"></bean>         //初始化一个切面对象
<aop:config>
   <aop:aspect ref="log">      //装配一个切面
     <aop:pointcut          //定义切入点
            expression="execution(* net.xinqushi.dao.impl.*.*(..))" id="pt"/>       
<aop:before method="before" pointcut-ref="pt"/>
    <aop:after method="after" pointcut-ref="pt"/>
   </aop:aspect>
</aop:config>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

行云的逆袭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值