SSM之接口调用与IOC注入达到解耦效果、spring web模块

学习目标

  • (1)Spring面向接口编程
  • (2)Spring和web结合
  • (3)Spring和junit的整合*
  • (4)SpringJDBCTemplate增删改查
  • (5)Spring的AOP*

Spring面向接口编程-创建Web项目

接口作用:解耦合

  • (1)创建Project Maven
  • (2)创建Module web app Maven
  • (3)设置java,reousrces,test
  • (4)配置依赖pom.xml
<dependencies>
        <!--spring依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.2.9.RELEASE</version>
        </dependency>

        <!--日志包-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

Spring面向接口编程-原理

类 跟 接口 是实现关系

  • (1)接口定义
    业务类接口com.xxx.service.IXxxService
    Dao接口 com.xxx.dao. IXxxDao
  • (2)实现类
    com.xxx.service.impl.XxxServiceImpl
    com.xxx.dao.impl. XxxDaoImpl
  • (3)一个接口有多个实现类,使用接口调用,将来更换实现类时,代码耦合底更低
    判断方法:删除法
    将来实现类对象由Spring管理,成员变量使用依赖注入

TestPersonService

@Test
    public void test01(){
        //用户的一个功能 ,通常对应咱们的一个业务 方法
        //IPersonService  PersonServiceImpl
        //PersonServiceImpl  PersonServiceImpl
        //PersonServiceImpl personService = new PersonServiceImpl();
        IPersonService personService = new PersonServiceImpl();
        //调了一个login
        Person person = new Person();
        boolean flag = personService.login(person);
        System.out.println(flag);

    }

IPersonService

public interface IPersonService {
    boolean login(Person person);
}

PersonDaoImpl

//类跟接口是实现关系
public class PersonServiceImpl implements IPersonService {

    private IPersonDao dao = new PersonDaoImpl();
    @Override
    public boolean login(Person person) {
        //..调用dao方法
       boolean flag =  dao.findByUserNameAndPassword(person);
       return flag;
    }
}

Person

public class Person {
    private String username;
    private String password;

IPersonDao

public interface IPersonDao {
     boolean findByUserNameAndPassword(Person person);
}

PersonDaoImpl

public class PersonDaoImpl implements IPersonDao {
    public boolean findByUserNameAndPassword(Person person) {
        return true;
    }
}

Spring面向接口编程-实现

  • (1)PersonServiceImplTest
  • (2)IPersonService
  • (3)PersonServiceImpl
  • (4)IPersonDao
  • (5)PersonDaoImpl
  • (6)Spring 注解 扫描
  • (7)Spring DI
    变量等号左边使用接口调用方法,加上 spring的getBean或者注解注入 可以达成实现类的解耦
    PersonServiceImplTest
    当前程序与PersonServiceImpl没有耦合
    ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
        IPersonService personService = (IPersonService) context.getBean("personServiceImpl");
        System.out.println(personService);

PersonServiceImpl
当前程序与PersonDaoImpl没有耦合

//类跟接口是实现关系
@Service
public class PersonServiceImpl implements IPersonService {

    //private IPersonDao dao = new PersonDaoImpl();
    @Autowired
    private IPersonDao dao;
    @Override
    public boolean login(Person person) {
        //..调用dao方法
       boolean flag =  dao.findByUserNameAndPassword(person);
       return flag;
    }
}

Spring面向接口编程-指定实现类(SpringAutowired与Qualifier)

  • (1)@Autowired:Spring会自动创建实现类对象,并且将实现类对象赋值给dao
    如果项目中有该接口只有一个实现类,可以使用Autowired
    但是,接口有两个或者两个以上的实现类,此时抛异常
    如:PersonDaoImpl StudentDaoImp
  • (2)@Qualifier:可以手动指定将哪一个实现类的对象赋值给IPersonDao接口
  • (3)两个必须合在一起使用
public class A{
@Autowired
@Qualifier("id值")  默认类名首字母小写
 private B b;
}
@Repository
public class PersonDaoImpl implements IPersonDao {
    public boolean findByUserNameAndPassword(Person person) {
        return true;
    }
}

@Repository
public class StudentDaoImpl implements IPersonDao {
    public boolean findByUserNameAndPassword(Person person) {
        return true;
    }
}

因为接口有两个实现类

//类跟接口是实现关系
@Service
public class PersonServiceImpl implements IPersonService {
    //private IPersonDao dao = new PersonDaoImpl();
    @Autowired
    @Qualifier("personDaoImpl")
    private IPersonDao dao;
}

Spring和web结合-代码实现

  • (1)复制一个模块
  • (2)依赖配置
  • (3)编写LoginServlet
 <!--servlet相关的3个jar包-->
    <dependency>
        <groupId>jstl</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
        <scope>provided</scope>
    </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>javax.servlet.jsp-api</artifactId>
            <version>2.2.1</version>
            <scope>provided</scope>
        </dependency>

LoginServlet

@WebServlet("/login")
public class LoginServlet extends HttpServlet {
    private static final Logger logger = LoggerFactory.getLogger(LoginServlet.class);
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
            doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获取账号密码
        String username=request.getParameter("username");
        String password=request.getParameter("password");
        logger.debug(username);
        logger.debug(password);
        //调用登录方法
        ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
        IPersonService personService = (IPersonService) context.getBean("personServiceImpl");
        Person person = new Person(username,password);

        boolean flag = personService.login(person);
        logger.debug(flag+" doGet ");
        //结果
        response.getWriter().println(flag?"success":"error");
    }
}

Spring和web结合-代码优化1
PersonServiceImpl service = (PersonServiceImpl) context.getBean(“PersonServiceImpl”));

  • (1)代码中有没有使用接口?
  • (2)代码中写死配置信息? 如:实现类
    》info.properties
    》Properties
    》getProperty(key)
   //从配置文件中取数据 .properties  Properties
   Properties p = new Properties();
   InputStream is = LoginServlet.class.getClassLoader().getResourceAsStream("info.properties");
   p.load(is);
        //调用登录方法

   ClassPathXmlApplicationContext context=new ClassPathXmlApplicationContext(p.getProperty("config"));
   IPersonService personService = (IPersonService) context.getBean(p.getProperty("serviceId"));

Spring和web结合-代码优化2

  • (1)doGet或者doPost什么时候执行?引起什么问题?
  • (2)一个程序只有一个实例
    》单例模式
    》ServletContext有什么用?
    支持多个Servlet共享数据且整个项目只有一个实例

ContextLoaderListener介绍

(1)ContextLoaderListener是什么?
》Spring编写了一个监听器,该监听器监听ServletContext对象的创建
(2)ContextLoaderListener有什么用?
会自动读取contextConfigLocation配置 ,并创建IOC容器
将IOC容器保存在ServletContext中
(3)如何使用?
》》依赖spring-web
》》在web.xml中配置监听器
在这里插入图片描述
pom.xml

 <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>5.2.9.RELEASE</version>
</dependency>

web.xml

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>

  <listener>
    <!--
      监听ServletContext对象创建,然后将spring容器放到该ServletContext中缓存起来
    -->
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

LoginServlet

// ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(p.getProperty("config"));
//1:从ServletContext域对象获取Spring容器
WebApplicationContext context = (WebApplicationContext) getServletContext().getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值