spring几大核心功能

1.IOC/DI(控制反转/依赖注入)

IOC是什么?IOC完成的事情是原先程序员主动通过new实例化对象的事情,转交给spring负责

IOC最大的作用是:解耦,程序员不需要管理对象,解除了对象管理和程序员之间的耦合

2.AOP(面向切面编程)

3.声明式事务

spring框架重要的概念:容器(container):spring当作一个容器

Spring 框架采用分层架构,根据不同的功能被划分成了多个模块,这些模块大体可分为 Data Access/Integration、Web、AOP、Aspects、Messaging、Instrumentation、Core Container 和 Test(见上图)

详细见:http://c.biancheng.net/view/4242.html

spring创建对象的三种方式

1.通过构造方法创建

  1.1 在applicationContext.xml中设置哪个构造方法创建对象

 <!-- 无参实例 -->
<bean id="pro" class="com.spring.po.People"></bean>
<!-- 有参实例 -->
<bean id="pro2" class="com.spring.po.People">
<!-- ref:引用另一个bean value:基本数据类型或String等 -->
<constructor-arg index="0" name="id" type="int" value="2"></constructor-arg>
<constructor-arg index="1" name="name" type="String" value="有参构造实例"></constructor-arg>
</bean>

  1.2 如果设定的条件匹配多个构造方法,则执行最后的构造方法

  1.3 index:参数的索引,从0开始,name:参数名,type:类型(区分关键字和封装类,例 int和integer)

2.实例工厂

  2.1 工厂设计模式:帮助创建类对象,一个工厂可以生产多个对象

  2.2 实例工厂:需要先创建工厂,才能生产对象,然后在xml中配置工厂对象和需要创建的对象

package com.spring.po;

public class PeopleFactory {
public People newInstance(){
return new People(3,"实例工厂");
}
}
     <!-- 实例工厂实现实例 -->
<bean id="factory" class="com.spring.po.PeopleFactory"></bean>
<bean id="pro3" factory-bean="factory" factory-method="newInstance"></bean>

3.静态工厂:编写一个静态工厂,在方法上添加static

package com.spring.po;

public class PeopleStaticFactory {
public static People newInstance(){
return new People(4, "静态");
} }
<!-- 静态工厂实例实例 -->
<bean id="pro4" class="com.spring.po.PeopleStaticFactory" factory-method="newInstance"></bean>

具体案例

IDE:myeclipse2017

jar包:spring4个基础jar包(本案例使用5.2版本)+Commons-logging的jar包

新建项目spring01,项目结构图如下

applicationContext.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!--
id:表示对象标识
class:创建哪个类的对象
-->
<!-- 无参实例 -->
<bean id="pro" class="com.spring.po.People"></bean>
<!-- 有参实例 -->
<bean id="pro2" class="com.spring.po.People">
<!-- ref:引用另一个bean value:基本数据类型或String等 -->
<constructor-arg index="0" name="id" type="int" value="2"></constructor-arg>
<constructor-arg index="1" name="name" type="String" value="有参构造实例"></constructor-arg>
</bean> <!-- 实例工厂实现实例 -->
<bean id="factory" class="com.spring.po.PeopleFactory"></bean>
<bean id="pro3" factory-bean="factory" factory-method="newInstance"></bean> <!-- 静态工厂实例实例 -->
<bean id="pro4" class="com.spring.po.PeopleStaticFactory" factory-method="newInstance"></bean>
</beans>

com.spring.po包

People.java

package com.spring.po;

public class People {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "People [id=" + id + ", name=" + name + "]";
} public People() {
super();
}
public People(int id,String name){
this.id=id;
this.name=name;
System.out.println("有参构造函数");
}
}

PeopleFactory.java

package com.spring.po;

public class PeopleFactory {
public People newInstance(){
return new People(3,"实例工厂");
}
}

PeopleStaticFactory.java

package com.spring.po;

public class PeopleStaticFactory {
public static People newInstance(){
return new People(4, "静态");
} }

com.spring.test包

Test.java

package com.spring.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.spring.po.People; public class Test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
People people= ac.getBean("pro",People.class);
people.setId(1);
people.setName("测试"); People people2=ac.getBean("pro2",People.class); People people3=ac.getBean("pro3",People.class); People people4=ac.getBean("pro4",People.class); System.out.println(people);
System.out.println(people2);
System.out.println(people3);
System.out.println(people4);
}
}

运行结果如下


使用spring简化mybatis

IDE:myeclipse2017

数据库的airport表数据

 项目具体代码在后面

1.导入mybatis所有jar包和spring基本jar包,spring-idbc,spring-tx,spring-aop,spring-web

2.编写spring配置文件applicationContext.xml

3.编写代码

  3.1 正常编写po(实体类)

  3.2 编写Mapper包下时必须使用接口绑定方案或注解方案(必须有接口)

  3.3 正常编写service接口和service实现类(impl)

    3.3.1 需要在service实现类中声明Mapper接口对象,并生成get/set方法

  3.4 spring无法管理servlet

案例

结构图

applicationContext.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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 数据源封装类,获取数据库连接 -->
<bean id="dataSouce" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</bean>
<!-- 创建SqlSessionFactory对象 -->
<bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 数据库连接信息,来源于dataSouce -->
<property name="dataSource" ref="dataSouce"></property>
</bean>
<!-- 扫描器相当于mybatis.xml中的Mapper下的backage标签 ,扫描com.spring.mapper后会给对应的接口创建对象-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 要扫描的包 -->
<property name="basePackage" value="com.spring.mapper"></property>
<!-- 和Factory产生关系 -->
<property name="sqlSessionFactory" ref="factory"></property>
</bean>
<!-- 由spring管理service -->
<bean id="airportService" class="com.spring.service.impl.AirportServiceImpl">
<property name="airportMapper" ref="airportMapper"></property>
</bean>
</beans>

com.spring.po包

Airport.java

package com.spring.po;

public class Airport {
private int id;
private String portName;
private String cityName;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getPortName() {
return portName;
}
public void setPortName(String portName) {
this.portName = portName;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
} @Override
public String toString() {
return "Airport [id=" + id + ", portName=" + portName + ", cityName=" + cityName + "]";
} }

com.spring.mapper包

AirportMapper.java

package com.spring.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Select;

import com.spring.po.Airport;

public interface AirportMapper {
@Select("select * from airport")
List<Airport> selAll();
}

com.spring.service包

AirportService.java

package com.spring.service;

import java.util.List;

import com.spring.po.Airport;

public interface AirportService {
List<Airport> show();
}

com.spring.service.impl包

AirportServiceImpl.java

package com.spring.service.impl;

import java.util.List;

import com.spring.mapper.AirportMapper;
import com.spring.po.Airport;
import com.spring.service.AirportService; public class AirportServiceImpl implements AirportService{
private AirportMapper airportMapper; public AirportMapper getAirportMapper() {
return airportMapper;
} public void setAirportMapper(AirportMapper airportMapper) {
this.airportMapper = airportMapper;
} @Override
public List<Airport> show() {
return airportMapper.selAll();
} }

com.spring.test包

Test.java

可以测试运行test

package com.spring.test;

import java.util.List;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.spring.po.Airport;
import com.spring.service.impl.AirportServiceImpl; public class Test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
// String [] names=ac.getBeanDefinitionNames();
// for (String string : names) {
// System.out.println(string);
// } AirportServiceImpl bean= ac.getBean("airportService",AirportServiceImpl.class);
List<Airport> list=bean.show();
// System.out.println(list);
for (Airport airport : list) {
System.out.println(airport);
}
}
}

com.spring.servlet包

AirportServlet.java

package com.spring.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils; import com.spring.service.AirportService;
import com.spring.service.impl.AirportServiceImpl; @WebServlet("/airport")
public class AirportServlet extends HttpServlet {
private AirportService airportService; @Override
public void init() throws ServletException {
//对service实例化
WebApplicationContext ac=WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
airportService=ac.getBean("airportService",AirportServiceImpl.class);
} @Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setAttribute("list", airportService.show());
req.getRequestDispatcher("index.jsp").forward(req, resp);
} }

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<!-- 上下文参数 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<!-- spring配置文件 -->
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--封装了一个监听器,帮助加载spring的配置文件 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>

index.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head> <title>spring简化mybatis</title>
</head> <body>
<c:forEach items="${list }" var="as" >
${as.id } ${as.portName } ${as.cityName }<br/>
</c:forEach>
</body>
</html>

运行结果如下

AOP初使用

前置通知和后置通知

新建项目,结构图如下

applicationContext.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 配置通知类对象,在切面中引入 -->
<bean id="mybefore" class="com.spring.advice.MyBeforeAdvice"></bean>
<bean id="myafter" class="com.spring.advice.MyAfterAdvice"></bean>
<!-- 配置切面 -->
<aop:config>
<!-- 配置切点 -->
<aop:pointcut expression="execution(* com.spring.test.Demo.demo2())" id="mypoint"/>
<!-- 通知 -->
<aop:advisor advice-ref="mybefore" pointcut-ref="mypoint"/>
<aop:advisor advice-ref="myafter" pointcut-ref="mypoint"/>
</aop:config>
<!-- 配置Demo类,测试使用 -->
<bean id="demo" class="com.spring.test.Demo"></bean>
</beans>

com.spring.advice包

MyAfterAdvice.java

  arg0:切点方法返回值

  arg1:切点方法对象

  arg2:切点方法参数

  arg3:切点方法所在类对象

package com.spring.advice;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;

public class MyAfterAdvice implements AfterReturningAdvice{

    @Override
public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
System.out.println("执行后置通知"); } }

MyBeforeAdvice.java

  arg0:切点方法对象Method

  arg1:切点方法参数

  arg2:切点在哪个对象中

package com.spring.advice;

import java.lang.reflect.Method;

import org.springframework.aop.MethodBeforeAdvice;

public class MyBeforeAdvice implements MethodBeforeAdvice {

    @Override
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
System.out.println("执行前置通知"); } }

com.spring.test包

Demo.java

package com.spring.test;

public class Demo {
public void demo1(){
System.out.println("demo1");
} public void demo2(){
System.out.println("demo2");
} public void demo3(){
System.out.println("demo3");
}
}

Test.java

package com.spring.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test {
public static void main(String[] args) {
// Demo demo=new Demo();
// demo.demo1();
// demo.demo2();
// demo.demo3(); ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
Demo demo=ac.getBean("demo",Demo.class);
demo.demo1();
demo.demo2();
demo.demo3();
}
}

结果如下

异常通知(Aspectj方式)

新建类,写任意名称的方法

package com.spring.advice;

public class MyThrowAdvice {
public void myexception(Exception e){
System.out.println("执行异常通知,异常message:"+e.getMessage());
}
}

在spring配置文件中配置

  <aop:cnfig>中的ref属性表示:方法在哪个类中

  <aop:after-throwing>表示异常通知

  method:当触发这个通知,调用哪个方法

  throuing:异常对象名,若使用throwing,则值必须和通知中的方法参数名相同(可以不在通知中声明异常对象,throwing可省略)

    <bean id="mythrow" class="com.spring.advice.MyThrowAdvice"></bean>
<aop:config>
<aop:aspect ref="mythrow">
<aop:pointcut expression="execution(* com.spring.test.Demo.demo1())" id="mypoint"/>
<aop:after-throwing method="myexception" pointcut-ref="mypoint" throwing="e"/>
</aop:aspect>
</aop:config>
<bean id="demo" class="com.spring.test.Demo"></bean>

demo1()方法

    public void demo1() throws Exception{
int num=5/0;
System.out.println("demo1");
}

Test类main

        ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
Demo demo=ac.getBean("demo",Demo.class);
try {
demo.demo1();
} catch (Exception e) { }

结果如下

环绕通知

把前置通知和后置通知都写到一个通知中,组成了环绕通知

新建类,实现MethodInterceptor

package com.spring.advice;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation; public class MyArround implements MethodInterceptor { @Override
public Object invoke(MethodInvocation arg0) throws Throwable {
System.out.println("环绕-前置");
Object result=arg0.proceed();
System.out.print("环绕-后置");
return result;
} }

xml配置文件

    <!-- 环绕通知 -->
<bean id="myarround" class="com.spring.advice.MyArround"/>
<aop:config>
<aop:pointcut expression="execution(* com.spring.test.Demo.demo2())" id="mypoint"/>
<aop:advisor advice-ref="myarround" pointcut-ref="mypoint"/>
</aop:config> <!-- 配置Demo类,测试使用 -->
<bean id="demo" class="com.spring.test.Demo"></bean>

main()方法

    public static void main(String[] args) {
// Demo demo=new Demo();
// demo.demo1();
// demo.demo2();
// demo.demo3(); ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
Demo demo=ac.getBean("demo",Demo.class);
/*try {
demo.demo1();
} catch (Exception e) { }*/
demo.demo2();
// demo.demo3();
}

结果如下

自定义通知

新建类,MyAdvice.java

package com.spring.advice;

import org.aspectj.lang.ProceedingJoinPoint;

public class MyAdvice {
public void mybefore(){
System.out.println("前置通知");
} public void myafter(){
System.out.println("后置通知1");
} public void myaftering(){
System.out.println("后置通知2");
} public void mythrow(){
System.out.println("异常通知");
} public Object myarround(ProceedingJoinPoint p) throws Throwable{
System.out.println("执行环绕");
System.out.println("执行环绕前置");
Object result=p.proceed();
System.out.println("环绕后置");
return result;
}
}

xml配置文件

    <bean id="myadvice" class="com.spring.advice.MyAdvice"></bean>
<aop:config>
<aop:aspect ref="myadvice">
<aop:pointcut expression="execution(* com.spring.test.Demo.demo1())" id="mypoint"/>
<!-- 前置通知 -->
<aop:before method="mybefore" pointcut-ref="mypoint"/>
<!-- 后置通知:alter有异常,依旧执行 -->
<aop:after method="myafter" pointcut-ref="mypoint"/>
<!-- 后置通知:alter-returning有异常,不执行 -->
<aop:after-returning method="myaftering" pointcut-ref="mypoint"/>
<!-- 异常通知 -->
<aop:after-throwing method="mythrow" pointcut-ref="mypoint"/>
<!-- 环绕通知 -->
<aop:around method="myarround" pointcut-ref="mypoint"/>
</aop:aspect>
</aop:config> <!-- 配置Demo类,测试使用 -->
<bean id="demo" class="com.spring.test.Demo"></bean>

demo类

public void demo1() throws Exception{
int num=5/0;
System.out.println("demo1");
}

可注释num=5/0,来显示不同结果

自动注入

在spring配置文件中对象名和ref="id",id名相同可以使用自动注入,不配置<property/>

2种配置方法

在<bean>中通过autowire=""  配置,只对这个<bean>生效

在<beans>中通过default-autowire="“  配置,表示当前文件中所有<bean>都是全局配置内容

autowire="",可取值

  default:默认值,根据全局default-autowire="“值,默认全局和局部都没有配置情况下,相当”no“

  no:不自动注入

  byName:通过名称自动注入,在spring容器中找类的id

  byType:根据类型注入(使用byType,则在spring容器不可以出现相同类型的<bean>)

  constructor:根据构造方法注入

    提供对应参数的构造方法(构造方法参数中包含注入对象那个)

    底层使用byName,构造方法参数名和其他<bean>的id相同

练习

新建项目,项目结构图如下

lib

数据库

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>

log4j.properties

# Global logging configuration
log4j.rootLogger=INFO,stdout,R
# MyBatis logging configuration...
log4j.logger.com.mybatis=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n log4j.appender.R=org.apache.log4j.DailyRollingFileAppender
log4j.appender.R.File=D\:\\temp\\logs\\qc.log
log4j.appender.R.layout=org.apache.log4j.PatternLayout
1log4j.appender.R.layout.ConversionPattern=%5p [%t] - %m%n

applicationContext.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:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd"
default-autowire="byName">
<!-- 数据源封装类,获取数据库连接 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC"></property>
<property name="username" value="root"></property>
<property name="password" value="123456"></property>
</bean>
<!-- 创建SqlSessionFactory对象 -->
<bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 数据库连接信息,来源于dataSouce -->
<!-- <property name="dataSource" ref="dataSource"></property> -->
<!-- 起别名 -->
<property name="typeAliasesPackage" value="com.spring.po"></property>
</bean>
<!-- 扫描器相当于mybatis.xml中的Mapper下的backage标签 ,扫描com.spring.mapper后会给对应的接口创建对象-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 要扫描的包 -->
<property name="basePackage" value="com.spring.mapper"></property>
<!-- 和Factory产生关系 -->
<property name="sqlSessionFactory" ref="factory"></property>
</bean>
<!-- 由spring管理service -->
<bean id="usersService" class="com.spring.service.impl.UsersServiceImpl">
<!-- <property name="usersMapper" ref="usersMapper"></property> -->
</bean>

<bean id="mybefore" class="com.spring.advice.MyBefore"></bean>
<bean id="myAfter" class="com.spring.advice.MyAfter"></bean>
<!-- aop -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
<aop:config>
<aop:pointcut expression="execution(* com.spring.service.impl.UsersServiceImpl.login(..))" id="mypoint"/>
<aop:advisor advice-ref="mybefore" pointcut-ref="mypoint"/>
<aop:advisor advice-ref="myAfter" pointcut-ref="mypoint"/>
</aop:config>
</beans>

com.spring.po包

Users.java

package com.spring.po;

public class Users {
private int id;
private String username;
private String password;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
} }

com.spring.mapper包

UsersMapper.java

package com.spring.mapper;

import com.spring.po.Users;

public interface UsersMapper {
Users selByUsers(Users users);
}

UsersMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.spring.mapper.UsersMapper">
<select id="selByUsers" parameterType="users" resultType="users">
select * from users where username=#{username} and password=#{password}
</select>
</mapper>

com.spring.service包

UsersService.java

package com.spring.service;

import com.spring.po.Users;

public interface UsersService {
Users login(Users users);
}

com.spring.service.impl包

package com.spring.service.impl;

import com.spring.mapper.UsersMapper;
import com.spring.po.Users;
import com.spring.service.UsersService; public class UsersServiceImpl implements UsersService {
private UsersMapper usersMapper; public UsersMapper getUsersMapper() {
return usersMapper;
} public void setUsersMapper(UsersMapper usersMapper) {
this.usersMapper = usersMapper;
} @Override
public Users login(Users users) {
return usersMapper.selByUsers(users);
} }

com.spring.servlet包

LoginServlet.java

package com.spring.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils; import com.spring.po.Users;
import com.spring.service.UsersService;
import com.spring.service.impl.UsersServiceImpl; @WebServlet("/login")
public class LoginServlet extends HttpServlet {
private UsersService usersService; @Override
public void init() throws ServletException {
WebApplicationContext wac=WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
usersService=wac.getBean("usersService",UsersServiceImpl.class);
} @Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
Users users=new Users();
users.setUsername(req.getParameter("username"));
users.setPassword(req.getParameter("password"));
Users user=usersService.login(users);
if(user!=null){
resp.sendRedirect("main.jsp");
}
else {
resp.sendRedirect("login.jsp");
}
} }

com.spring.test包

Test  测试用的

    package com.spring.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test {
public static void main(String[] args) {
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
String [] names=ac.getBeanDefinitionNames();
for (String string : names) {
System.out.println(string);
}
}
}

com.spring.advice包

MyAfter.java

package com.spring.advice;

import java.lang.reflect.Method;

import org.apache.log4j.Logger;
import org.springframework.aop.AfterReturningAdvice; import com.spring.po.Users; public class MyAfter implements AfterReturningAdvice { @Override
public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
Logger logger=Logger.getLogger(MyAfter.class);
Users users=(Users)arg2[0];
if(arg0!=null){
logger.info(users.getUsername()+"登录成功!");
}else {
logger.info(users.getUsername()+"登录失败!");
} } }

MyBefore.java

package com.spring.advice;

import java.lang.reflect.Method;
import java.util.Date; import org.apache.log4j.Logger;
import org.springframework.aop.MethodBeforeAdvice; import com.spring.po.Users; public class MyBefore implements MethodBeforeAdvice { @Override
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
Users users=(Users)arg1[0];
Logger logger=Logger.getLogger(MyBefore.class);
logger.info(users.getUsername()+"在"+new Date().toLocaleString()+"进行登录");
} }

login.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>My JSP 'login.jsp' starting page</title>
</head> <body>
<form action="login" method="post">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br/>
<input type="submit" value="登录">
</form>
</body>
</html>

运行

spring中加载properties文件

1.在src下新建xxx.properties文件

2.在spring配置文件中引入xmlns:context,在下面添加,如果需要加载多个配置文件,用逗号分隔

  <context:property-placeholder location="classpath:xxx.properties"/>

3.添加了属性文件,并且在<beans>中开启自动注入,需要注意的地方

  3.1 SqlSessionFactoryBean的id不能叫做sqlSessionFactory

  3.2 修改扫描器(MapperScannerConfigurer),把原来ref引用替换value赋值,自动注入只能影响ref,不会影响value赋值

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 要扫描的包 -->
<property name="basePackage" value="com.spring.mapper"></property>
<!-- 和Factory产生关系 -->
<property name="sqlSessionFactoryBeanName" value="factory"></property>
</bean>

4.在被spring管理的类通过@Value("${key}")取出properties中的内容

  4.1添加注解扫描

<context:component-scan base-package="com.spring.service.impl"></context:component-scan>

  4.2在类中添加

    key和变量名可以不相同

    变量类型任意,只要保证key对应的value能转换成这个类型就可以

示例

在上个项目中src下添加db.properties和second.properties

second.properties

my.demo=hello
my.demo1=123

db.properties

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC
jdbc.username=root
jdbc.pwd=123456

修改UsersServiceImpl.java

package com.spring.service.impl;

import org.springframework.beans.factory.annotation.Value;

import com.spring.mapper.UsersMapper;
import com.spring.po.Users;
import com.spring.service.UsersService; public class UsersServiceImpl implements UsersService {
@Value("${my.demo}")
private String test; @Value("${my.demo1}")
private String test1; private UsersMapper usersMapper; public UsersMapper getUsersMapper() {
return usersMapper;
} public void setUsersMapper(UsersMapper usersMapper) {
this.usersMapper = usersMapper;
} @Override
public Users login(Users users) {
System.out.println("输出:"+test+" "+test1); return usersMapper.selByUsers(users);
} }

修改applicationContext.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd"
default-autowire="byName">
<context:property-placeholder location="classpath:db.properties,classpath:second.properties"/>
<context:component-scan base-package="com.spring.service.impl"></context:component-scan>
<!-- 数据源封装类,获取数据库连接 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.pwd}"></property>
</bean>
<!-- 创建SqlSessionFactory对象 -->
<bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 数据库连接信息,来源于dataSouce -->
<!-- <property name="dataSource" ref="dataSource"></property> -->
<!-- 起别名 -->
<property name="typeAliasesPackage" value="com.spring.po"></property>
</bean>
<!-- 扫描器相当于mybatis.xml中的Mapper下的backage标签 ,扫描com.spring.mapper后会给对应的接口创建对象-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 要扫描的包 -->
<property name="basePackage" value="com.spring.mapper"></property>
<!-- 和Factory产生关系 -->
<!-- <property name="sqlSessionFactory" ref="factory"></property> -->
<property name="sqlSessionFactoryBeanName" value="factory"></property>
</bean>
<!-- 由spring管理service -->
<bean id="usersService" class="com.spring.service.impl.UsersServiceImpl">
<!-- <property name="usersMapper" ref="usersMapper"></property> -->
</bean> <bean id="mybefore" class="com.spring.advice.MyBefore"></bean>
<bean id="myAfter" class="com.spring.advice.MyAfter"></bean>
<!-- aop -->
<aop:aspectj-autoproxy proxy-target-class="true"></aop:aspectj-autoproxy>
<aop:config>
<aop:pointcut expression="execution(* com.spring.service.impl.UsersServiceImpl.login(..))" id="mypoint"/>
<aop:advisor advice-ref="mybefore" pointcut-ref="mypoint"/>
<aop:advisor advice-ref="myAfter" pointcut-ref="mypoint"/>
</aop:config>
</beans>

运行登录,控制台结果如下

scope属性

1.<bean>的属性

2.作用:控制对象有效范围(单例,多例)

3.<bean>标签对应的对象默认是单例的,无论获取多少次,都是一个对象

4.scope可取值

  singleton  默认值,单例

  prototype  多例,每次获取重新实例化

  request  每次请求重新实例化

  session  每次会话对象内,对象内是单例的

  application  在application对象内是单例的

  

spring中常用的两种事务配置方式以及事务的传播性,隔离性

参考https://www.cnblogs.com/dj66194/p/7654555.html,感谢“还有梦”

spring中常用注解

1.@Component:创建类对象,相当于配置<bean>

2.@Service:与Component功能相同,写在serviceImpl类上

3.@Repository:与Component功能相同,写在数据访问层类上

4.@Controller:与Component功能相同,写在控制器类上

5.@Resource:不需要写对象的get/set,java中的注解,默认按照byName注入,如果没有名称对象,则按照byType注入,建议把对象名称和spring容器中对象名相同

6.@Autowired:不需要写对象的get/set,spring注解,默认按照byType注入

7.@Value():获取properties文件内容

8.@Pointcut():定义切点

9.@ASpect():定义切面类

10.@Before():前置通知

11.@Alter:后置通知

12.@AlterReturning:后置通知,切点须正确执行

13.@AlterThrowing:异常通知

14.@Around:环绕通知

spring自学历程的更多相关文章

  1. 分享一下我的Python自学历程,分享下我自己学习方法

    其实关于编程这事儿没有接触的那么早,大一的时候没什么关注点,有一门课是vb,一天天的,就抄抄作业啥的就完事儿了.当时也觉的自己不是学编程的料,想着以后估摸也不会干开发相关的工作. 我的自学历程 阴差阳 ...

  2. Himi浅谈游戏开发de自学历程!(仅供参考)

    李华明Himi原创,转载务必在明显处注明: 转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/himistudy/382.html ☞ 点击订阅 ☜ 本博客 ...

  3. Spring发展历程总结

    目前很多公司的架构,从Struts2迁移到了SpringMVC.你有想过为什么不使用Servlet+JSP来构建Java web项目,而是采用SpringMVC呢? 既然这样,我们从源头说起.Stru ...

  4. Spring自学教程-ssh整合(六)

    以下是本人原创,如若转载和使用请注明转载地址.本博客信息切勿用于商业,可以个人使用,若喜欢我的博客,请关注我,谢谢!博客地址 感谢您支持我的博客,我的动力是您的支持和关注!如若转载和使用请注明转载地址 ...

  5. Spring自学教程-AOP学习(五)

    Spring中的AOP 一.概述 (一)基本概念 1.什么是AOP?     面向方面编程.所谓方面即是指日志.权限.异常处理.事务处理等. 2.AOP的3个关键概念    (1)切入点(Pointc ...

  6. Spring自学教程-声明式事务处理(六)

    Spring事务处理分两种: 一.编程式事务:在程序中控制事务开始,执行和提交: 1.1 使用TransactionTemplate, 使用回调函数执行事务,不需要显示开始事务,不需要显示提交事务,但 ...

  7. Spring自学教程-jabc编程详解、RowMapper使用(三)

    一.JDBC 1.JDBC的编程特点 静态代码+动态变量 = jdbc编程.在spring中动态变量可以用注入的形式给予.这样的编程方式适合包装成模板.静态代码构成了模板,而动态变量则是需要传入的参数 ...

  8. Spring自学教程-注解的使用(三)

    一.java中的注解 定义注解 下面是一个定义注解的实例. @Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)@Documente ...

  9. Spring自学教程-IOC、DI、AOP(二)

    一.spring的IOC-就是怎样使用spring来创建对象 二.springDI(依赖注入)-就是怎样给属性赋值 通过set方式赋值 以下我们只需要记住两点的赋值,基本类型和引用类型的赋值 基本类型 ...

随机推荐

  1. Hibernate入门教程(二):Hibernate核心API

    1.Configuraction onfiguration configuration = new Configuration(); configuration.configure(); 到src下面 ...

  2. SQL语句优化方式--进阶篇

    MYSQL性能 最大数据量 抛开数据量和并发数,谈性能都是扯淡(扯的最疼的那种).Mysql没有限制单表最大记录数,它取决与操作系统对文件大小的限制 文件系统 单文件大小限制 FAT32(采用32位二 ...

  3. 初识Flink广播变量broadcast

    Broadcast 广播变量:可以理解为是一个公共的共享变量,我们可以把一个dataset 或者不变的缓存对象(例如map list集合对象等)数据集广播出去,然后不同的任务在节点上都能够获取到,并在 ...

  4. SVD和SVD++

    参考自:http://blog.csdn.net/wjmishuai/article/details/71191945 http://www.cnblogs.com/Xnice/p/4522671.h ...

  5. centos7.3安装wordpress

    一.安装并配置数据库 1.安装mariadb #yum install -y mariadb-server mariadb 2.启动数据库并设置开机自启#systemctl start mariadb ...

  6. Javascript基础五(BOM和DOM)

    1.BOM概念 什么是BOM?         BOM是Browser Object Model的缩写,简称浏览器对象模型.这个对象就是window         BOM提供了独立于内容而与浏览器窗 ...

  7. 将循环结果通过管道 传递给其他命令处理(done |)

  8. MYSQL如何优化?

    MYSQL如何优化?结合你的经验 1.数据库的设计尽量把数据库设计的更小的占磁盘空间.1).尽可能使用更小的整数类型.(mediumint就比int更合适).2).尽可能的定义字段为not null, ...

  9. vscode 常用的插件

    这些是本人在使用vscode中用的比较爽的插件,个人爱好习惯不同,请按需拿取.先声明本人是一个前端,所用的,插件都是和前端匹配的,后台的同学可以不用浪费时间了 基础插件 chinese 英文是所有读书 ...

  10. matlab采用GPU运算

    >>help gpuThere are several options available for using your computer's graphics processing un ...