学习目标
- (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);