首页 > 其他分享 >Day20-spring

Day20-spring

时间:2023-07-31 23:23:58浏览次数:38  
标签:www spring Day20 springframework context org import public

Spring(容器框架)

官网:https://spring.io/projects/spring-framework

  1. 导入spring的包——-Spring Web MVC

    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>6.0.11</version>
    </dependency>
  2. 优点

    spring是容器框架用于配置bean,并维护bean之间关系的框架

    • bean是java中的任何一种对象,javabean/service/action/数据源/dao

    • ioc控制反转:inverse of control

    • aop面向切面

    • 支持事务

    • di依赖注入:dependency injection

总结:Spring就是一个轻量级的控制反转(IOC)和面向切面(AOP)编程的框架

  1. 组成

  2. 扩展

    • Spring Boot

      • 一个快速开发的脚手架

      • 基于SpringBoot可以快速的开发单个微服务

      • 约定大于配置

    • Spring Cloud

      • SpringCloud是基于SpringBoot实现的

IOC

HelloSpring

  1. 导包

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.lsq</groupId>
    <artifactId>Spring-Study</artifactId>
    <packaging>pom</packaging>
    <version>1.0-SNAPSHOT</version>
    <modules>
    <module>spring-01</module>
    </modules>

    <properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    </properties>

    <dependencies>
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.15.RELEASE</version>
    </dependency>
    </dependencies>

    <build>
    <resources>
    <resource>
    <directory>src/main/resources</directory>
    <includes>
    <include>**/*.properties</include>
    <include>**/*.xml</include>
    </includes>
    <filtering>false</filtering>
    </resource>
    <resource><!--源-->
    <directory>src/main/java</directory><!--你的文件所在路径-->
    <includes><!--包含哪些后缀名文件-->
    <include>**/*.properties</include>
    <include>**/*.xml</include>
    </includes>
    <filtering>false</filtering>
    </resource>
    </resources>
    </build>
    </project>
  2. 创建pojo对象

    package com.lsq.pojo;

    public class Hello {
    private String str;

    public String getStr() {
    return str;
    }

    public void setStr(String str) {
    this.str = str;
    }

    @Override
    public String toString() {
    return "Hello{" +
    "str='" + str + '\'' +
    '}';
    }
    }
  3. 编写配置文件

    <?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">

    <!--使用Spring来创建对象,在Spring中这些都称为Bean
    类型 变量名 = new 类型();
    bean = 对象 new Hello();
    id = 变量名
    class = new 的对象
    property相当于给对象中的属性设置一个值
    ref:引用Spring容器中创建好的对象
    value:具体的值,基本数据类型
    -->
    <bean id="hello" class="com.lsq.pojo.Hello">
    <property name="str" value="Spring"/>

    </bean>

    </beans>
  4. 测试

    import com.lsq.pojo.Hello;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class MyTest {
    public static void main(String[] args) {
    //获取Spring的上下文对象
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    //我们的对象现在都在Spring中管理了,我们要使用直接去里面取出来就可以
    Hello hello = (Hello)context.getBean("hello");
    System.out.println(hello.toString());
    }
    }

IOC创建对象的方式

  1. 使用无参构造创建对象,默认!

  2. 假设我们要使用有参构造创建对象

    1. 下标赋值

       <bean id="hello" class="com.lsq.pojo.Hello">
      <property name="str" value="Spring"/>
      </bean>
    2. 类型

      <!--第二种:通过类型创建,不建议使用-->
      <bean id="user" class="com.lsq.pojo.User">
      <constructor-arg index="0" type="java.lang.String" value="七七"/>
      </bean>
    3. 参数名

        <!--第三种:通过参数名来设置-->
      <bean id="user" class="com.lsq.pojo.User">
      <constructor-arg name="name" value="罐罐"/>
      </bean>

    总结:在配置文件加载的时候,容器中管理的对象就已经初始化了

Spring配置

1. 别名

 <!--如果配置了别名,也可以用别名获取到这个对象-->
<alias name="user" alias="user2"/>

2. Bean的配置

    <!--
id:bean的唯一标识符,也就是相当于我们的对象名
class:bean对象所对应的全限定名:包名+类型
name:也是别名,而且name可以同时取多个别名
-->

3. import

这个import,一般用于团队开发使用,他可以将多个配置文件,导入合并为一个

假设,现在项目中有多个人开发,这多个人负责不同的类开发,不同的类需要注册在不同的bean中,我们可以利用import将所有人的beans.xml合并为一个总的,使用的时候直接使用总的配置就可以了

依赖注入

构造器注入

Set方式注入【重点】

  • 依赖注入:Set注入

    • 依赖:bean对象的创建依赖于容器

    • 注入:bean对象中的所有属性,由容器来注入

【环境搭建】

  • 复杂类型

    package com.lsq.pojo;

    public class Address {
    private String address;

    public String getAddress() {
    return address;
    }

    public void setAddress(String address) {
    this.address = address;
    }
    }
  • 真实测试对象

    public class Student {
    private String name;
    private Address address;
    private String[] books;
    private List<String> hobbys;
    private Map<String ,String> card;
    private Set<String> games;
    private String wife;
    private Properties info;
    }
  • beans.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="student" class="com.lsq.pojo.Student">
    <!--第一种:普通值注入,value-->
    <property name="name" value="文姬"/>
    </bean>

    </beans>
  • 测试类

    import com.lsq.pojo.Student;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    public class MyTest {
    public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
    Student student = (Student)context.getBean("student");
    System.out.println(student.getAddress());
    }
    }
  • 完善注入信息

    <?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="address" class="com.lsq.pojo.Address">
    <property name="address" value="江西"/>
    </bean>
    <bean id="student" class="com.lsq.pojo.Student">
    <!--第一种:普通值注入,value-->
    <property name="name" value="文姬"/>

    <!--第二种:bean注入,ref-->
    <property name="address" ref="address"/>

    <!--数组注入-->
    <property name="books">
    <array>
    <value>红楼梦</value>
    <value>水浒传</value>
    <value>西游记</value>
    <value>三国演义</value>
    </array>
    </property>

    <!--list-->
    <property name="hobbys">
    <list>
    <value>听歌</value>
    <value>跳舞</value>
    <value>敲代码</value>
    <value>看电影</value>
    </list>
    </property>

    <!--map-->
    <property name="card">
    <map>
    <entry key="身份证" value="123456"/>
    <entry key="银行卡" value="123454567"/>
    </map>
    </property>

    <!--set-->
    <property name="games">
    <set>
    <value>LOL</value>
    <value>王者</value>
    <value>光遇</value>
    </set>
    </property>

    <!--null-->
    <property name="wife">
    <null/>
    </property>

    <!--Properties-->
    <property name="info">
    <props>
    <prop key="学号">170706052</prop>
    <prop key="姓名">刘文姬</prop>
    <prop key="性别">女</prop>
    </props>
    </property>

    </bean>


    </beans>

拓展方式注入

我们可以使用p命名空间和c命名空间进行注入

官方解释

使用

<?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:c="http://www.springframework.org/schema/c"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd">

<!--p命名空间注入,可以直接注入属性的值:property-->
<bean id="user" class="com.lsq.pojo.User" p:name="文姬" p:age="23"/>

<!--c命名空间注入,通过构造器注入:constructor-args-->
<bean id="user2" class="com.lsq.pojo.User" c:age="18" c:name="雅雅"/>
</beans>

测试

import com.lsq.pojo.Student;
import com.lsq.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {

@Test
public void test1(){
ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
User user = (User)context.getBean("user2");
System.out.println(user);
}
}

注意点:p命名和c命名空间不能直接使用,需要导入xml约束

xmlns:p="http://www.springframework.org/schema/p"
xmlns:c="http://www.springframework.org/schema/c"

bean的作用域

  1. 单例模式(Spring默认机制)

     <bean id="user2" class="com.lsq.pojo.User"scope="singleton"/>
  2. 原型模式:每次从容器中get的时候,都会产生一个新对象

    <bean id="user2" class="com.lsq.pojo.User" scope="prototype"/>
  3. 其余的request、session、application这些个只能在web开发中使用到

Bean的自动装配

  • 自动装配是Spring满足bean依赖一种方式

  • Spring会在上下文中自动寻找,并自动给bean装配属性

在Spring中有三种装配的方式

  1. 在xml中显示的配置

  2. 在java中显示配置

  3. 隐式的自动装配bean【重要】

ByName自动装配

  <!--
byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid
-->
<bean id="person" class="com.lsq.pojo.Person" autowire="byName">
<property name="name" value="雅雅"/>
</bean>

ByType自动装配

   <bean class="com.lsq.pojo.Cat"/>
<bean class="com.lsq.pojo.Dog"/>
<!--
byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean
-->
<bean id="person" class="com.lsq.pojo.Person" autowire="byType">
<property name="name" value="雅雅"/>
</bean>

使用注解实现自动装配

要使用注解须知

  1. 导入约束 :context约束

  2. 配置注解的支持 context:annotation-config/

    <?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: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/context
    https://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

    </beans>

@Autowired

直接在属性上使用即可!也可以在set方式上使用

使用Autowired我们可以不用编写Set方法,前提是你自动装配的属性在IOC(Spring)容器中存在,且符合名字byName

科普:

@Nullable 字段标记了这个注解,说明这个字段可以为null;
public @interface Autowired{
boolean requried() default true;
}

测试代码:

public class Person {
//如果显示定义了Autowired的required属性为false,说明这个对象可以为null,否则不允许为空
@Autowired(required = false)
private Cat cat;
@Autowired
private Dog dog;
private String name;
}

如果 @Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候、我们可以使用@Qualifer(value=“xxx”)去配置@Autowired的使用,指定一个唯一的bean对象注入

@Resource

public class Person {
@Resource(name = "cat")
private Cat cat;
private Dog dog;
private String name;
}

总结:

@Autowired和@Resource

  • 都是用来自动装配的,都可以放在属性字段上

  • @Autowired通过byName的方式实现,而且必须要求这个对象存在

  • @Resource默认通过byName的方式实现,如果找不到名字,则通过byType实现,如果两个都找不到的情况下,就报错

  • 执行顺序不同

    • @Autowired通过byType的方式实现

    • @Resource默认通过byName的方式实现

使用注解开发

在Spring4之后,要使用注解开发,必须要保证aop的包导入了

使用注解需要导入context约束

<?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: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/context
https://www.springframework.org/schema/context/spring-context.xsd">

<context:component-scan base-package="com.lsq.pojo"/>
<context:annotation-config/>

</beans>

  1. bean

  2. 属性如何注入

    @Component
    public class User {
    public String name;


    //相当于<property name="name" value="hahahah"/>
    @Value("hahahah")
    public void setName(String name) {
    this.name = name;
    }
    }
  3. 衍生的注解

    @Component有几个衍生注解,我们在web开发中会按照mvc三层架构分层

    • dao 【@Repository】

    • service 【@Service】

    • controller 【@Controller】

  4. 自动装配

    @Autowired:自动装配通过类型,名字
    如果@Autowired不能唯一自动装配上属性,则需要通过@Qualifier(value="xxx")
    @Nullable 字段标记了这个注解,说明这个字段可以为null
    @Resource 自动装配通过名字,类型
  5. 作用域

    @Component
    @Scope("singlton")
    public class User {
    public String name;


    //相当于<property name="name" value="hahahah"/>
    @Value("hahahah")
    public void setName(String name) {
    this.name = name;
    }
    }
  6. 小结

使用Java的方式配置Spring

配置类

package com.lsq.config;

import com.lsq.pojo.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

//这个也会被Spring容器托管,注册到容器中,因为他本来就是一个@Component
//@Configuration代表这是一个配置类,就和我们之前的备beans.xml一样
@Configuration
@ComponentScan("com.lsq.pojo")
@Import(MyConfig2.class)
public class MyConfig {

//注册一个bean,就相当于我们之前写的一个bean标签
//这个方法的名字,就相当于bean标签的id属性
//这个方法的返回值,就相当于bean标签中的class属性
@Bean
public User getUser(){
return new User(); //就是返回要注入到bean的对象
}

}

实体类

package com.lsq.pojo;

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

//这里这个注解的意思就是说明 这个类被Spring接管了,注册到了容器中
@Component
public class User {
private String name;

public String getName() {
return name;
}

@Value("文姬") //属性注入值
public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
'}';
}
}

测试类

import com.lsq.config.MyConfig;
import com.lsq.pojo.User;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class MyTest {
public static void main(String[] args) {
//如果完全是用了配置类方式去做,我们就只能通过AnnotationConfig上下文来获取容器,通过配置的class对象加载
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
User getUser = (User)context.getBean("getUser");
System.out.println(getUser.getName());
}
}

代理模式

静态代理

  1. 接口

    package com.lsq.demo01;

    //租房
    public interface Rent {
    public void rent();
    }
  2. 真实角色

    package com.lsq.demo01;

    public class Host implements Rent{
    @Override
    public void rent() {
    System.out.println("房东要出租房子");
    }
    }
  3. 代理角色

    package com.lsq.demo01;

    public class Proxy implements Rent{
    private Host host;

    public Proxy() {
    }

    public Proxy(Host host) {
    this.host = host;
    }

    @Override
    public void rent() {
    seeHouse();
    host.rent();
    hetong();
    fare();
    }

    //看房
    public void seeHouse(){
    System.out.println("中介带你看房");
    }

    //签租赁合同
    public void hetong(){
    System.out.println("签租赁合同");
    }

    //收中介费
    public void fare(){
    System.out.println("收中介费");
    }
    }
  4. 客户端访问代理角色

    package com.lsq.demo01;

    public class Client {
    public static void main(String[] args) {
    //房东要出租房子
    Host host = new Host();
    //代理,中介帮房东出租房子,但是代理角色一般会有一些附属操作
    Proxy proxy = new Proxy(host);
    proxy.rent();
    }
    }
    加深理解

    接口

    package com.lsq.demo02;

    public interface UserService {
    public void add();
    public void delete();
    public void update();
    public void query();
    }

    真实对象

    package com.lsq.demo02;

    //真实对象
    public class UserServiceImpl implements UserService{
    @Override
    public void add() {
    System.out.println("增加了一个用户");
    }

    @Override
    public void delete() {
    System.out.println("删除了一个用户");
    }

    @Override
    public void update() {
    System.out.println("更新了一个用户");
    }

    @Override
    public void query() {
    System.out.println("查询了一个用户");
    }
    }

    代理对象

    package com.lsq.demo02;

    public class UserServiceProxy implements UserService{

    private UserServiceImpl userService;


    public void setUserService(UserServiceImpl userService) {
    this.userService = userService;
    }

    @Override
    public void add() {
    log("add");
    userService.add();
    }

    @Override
    public void delete() {
    log("delete");
    userService.delete();
    }

    @Override
    public void update() {
    log("update");
    userService.update();
    }

    @Override
    public void query() {
    log("query");
    userService.query();
    }

    public void log(String message){
    System.out.println("使用了"+message+"方法");
    }
    }

    客户端

    package com.lsq.demo02;

    public class Client {
    public static void main(String[] args) {
    UserServiceImpl userService = new UserServiceImpl();
    UserServiceProxy userServiceProxy = new UserServiceProxy();
    userServiceProxy.setUserService(userService);
    userServiceProxy.add();
    }
    }

AOP

动态代理

  • 动态代理和静态代理角色一样

  • 动态代理的代理类是动态生成的,不是我们直接写的

  • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理

    • 基于接口——-JDK动态代理

    • 基于类:cglib

    • java字节码实现:javasist

    动态代理的好处:

    • 可以使真实角色操作更加纯粹,不用去关注一些公共的业务

    • 公共业务就交给代理角色,实现了业务的分工

    • 公共业务发生扩展的时候,方便集中管理

    • 一个动态代理类代理的是一个接口,一般就是对应一类业务

    • 一个动态代理类可以代理多个类,只要是实现了同一个接口即可

    package com.lsq.demo04;

    import com.lsq.demo03.Rent;

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;

    //用这个类自动生成代理类
    public class ProxyInvocationHandler implements InvocationHandler {
    //被代理的接口
    private Object target;

    public void setTarget(Object target) {
    this.target = target;
    }

    //生成得到代理类
    public Object getProxy(){
    return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this);
    }

    //处理代理实例,并返回结果
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    //动态代理的本质,就是使用反射机制实现
    Object result = method.invoke(target, args);
    return result;
    }
    }
    package com.lsq.demo04;

    import com.lsq.demo02.UserService;
    import com.lsq.demo02.UserServiceImpl;
    import com.lsq.demo03.Host;
    import com.lsq.demo04.ProxyInvocationHandler;
    import com.lsq.demo03.Rent;

    public class Client {
    public static void main(String[] args) {
    //真实角色
    UserServiceImpl userService = new UserServiceImpl();

    //代理角色:现在没有
    ProxyInvocationHandler pih = new ProxyInvocationHandler();

    //通过调用程序处理角色来处理我们要调用的接口对象
    pih.setTarget(userService);
    UserService proxy = (UserService)pih.getProxy();
    proxy.add();
    }
    }

使用Spring实现Aop

【重点】使用AOP织入,需要导入一个依赖包

 <dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.19</version>
</dependency>

方式一:使用Spring的API接口

接口

package com.lsq.service;

public interface UserService {
public void add();
public void delete();
public void update();
public void query();
}

实现类

package com.lsq.service;

public class UserServiceImpl implements UserService{
@Override
public void add() {
System.out.println("增加了一个用户");
}

@Override
public void delete() {
System.out.println("删除了一个用户");
}

@Override
public void update() {
System.out.println("修改了一个用户");
}

@Override
public void query() {
System.out.println("查询了一个用户");
}
}

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">

<!--注册bean-->
<bean id="userService" class="com.lsq.service.UserServiceImpl"/>
<bean id="log" class="com.lsq.log.Log"/>
<bean id="afterLog" class="com.lsq.log.AfterLog"/>

<!--配置AOP:需要导入aop的约束-->
<aop:config>
<!--切入点:expression:表达式,execution(要执行的位置! * * * * *)-->
<aop:pointcut id="pointcut" expression="execution(* com.lsq.service.UserServiceImpl.*(..))"/>
<!--执行环绕增加-->
<aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
<aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
</aop:config>
</beans>

测试

import com.lsq.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//动态代理代理的是接口
UserService userService = context.getBean("applicationContext.xml", UserService.class);
userService.add();
}
}

方式二:自定义来实现AOP

applicationContext.xml

   <bean id="diy" class="com.lsq.diy.DiyPointCut"/>
<aop:config>
<!--自定义切面,ref 要引用的类-->
<aop:aspect ref="diy">
<!--切入点-->
<aop:pointcut id="point" expression="execution(* com.lsq.service.UserServiceImpl.*(..))"/>
<!--通知-->
<aop:before method="before" pointcut-ref="point"/>
<aop:after method="after" pointcut-ref="point"/>
</aop:aspect>
</aop:config>

方式三:使用注解实现

<!--方式三:使用注解定义aop-->
<bean id="diy" class="com.lsq.diy.DiyPointCut"/>
<!--开启注解支持!JDK(默认proxy-target-class="false")cglib (proxy-target-class="true")-->
<aop:aspectj-autoproxy/>
package com.lsq.diy;

//方式三:使用注解方式实现aop

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect //标注这是一个切面
public class AnnotationPointcut {
@Before("execution(* com.lsq.service.UserServiceImpl.*(..))")
public void before(){
System.out.println("=========方法执行前========");
}

@After("execution(* com.lsq.service.UserServiceImpl.*(..))")
public void after(){
System.out.println("=========方法执行后========");
}

@Around("execution(* com.lsq.service.UserServiceImpl.*(..))")
public void around(ProceedingJoinPoint jp) throws Throwable {
System.out.println("环绕前");
Object proceed = jp.proceed();
Signature signature = jp.getSignature();
System.out.println(proceed);
System.out.println(signature);
System.out.println("环绕后");
}
}

整合mybatis

步骤:

  1. 导入jar包

    • junit

    • mybatis

    • mysql数据库

    • spring相关的包

    • aop织入

    • mybatis-spring【新包】

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
       <parent>
           <artifactId>Spring-Study</artifactId>
           <groupId>com.lsq</groupId>
           <version>1.0-SNAPSHOT</version>
       </parent>
       <modelVersion>4.0.0</modelVersion>

       <artifactId>spring-08</artifactId>

       <dependencies>
           <dependency>
               <groupId>junit</groupId>
               <artifactId>junit</artifactId>
               <version>4.13.2</version>
           </dependency>
           <dependency>
               <groupId>org.mybatis</groupId>
               <artifactId>mybatis</artifactId>
               <version>3.5.13</version>
           </dependency>
           <dependency>
               <groupId>mysql</groupId>
               <artifactId>mysql-connector-java</artifactId>
               <version>8.0.25</version>
           </dependency>
           <dependency>
               <groupId>org.springframework</groupId>
               <artifactId>spring-webmvc</artifactId>
               <version>5.2.15.RELEASE</version>
           </dependency>
           <dependency>
               <groupId>org.springframework</groupId>
               <artifactId>spring-jdbc</artifactId>
               <version>5.2.15.RELEASE</version>
           </dependency>
           <dependency>
               <groupId>org.aspectj</groupId>
               <artifactId>aspectjweaver</artifactId>
               <version>1.9.19</version>
           </dependency>
           <dependency>
               <groupId>org.mybatis</groupId>
               <artifactId>mybatis-spring</artifactId>
               <version>2.0.7</version>
           </dependency>
       </dependencies>

       <properties>
           <maven.compiler.source>8</maven.compiler.source>
           <maven.compiler.target>8</maven.compiler.target>
       </properties>

    </project>
  2. 编写配置文件

    <?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: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/context
               https://www.springframework.org/schema/context/spring-context.xsd">


           <!--DataSource:使用Spring的数据源替换Mybatis的配置 c3p0 dbcp druid-->
           <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
               <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
               <property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&amp;useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false"/>
               <property name="username" value="root"/>
               <property name="password" value="12345678"/>
           </bean>

           <!--sqlSessionFactory-->
           <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
               <property name="dataSource" ref="dataSource"/>
               <!--绑定Mybatis配置文件-->
               <property name="configLocation" value="classpath:mybatis-config.xml"/>
               <property name="mapperLocations" value="classpath:com/lsq/dao/UserMapper.xml"/>
           </bean>

           <!--sqlSessionTemplate:就是我们是用的sqlSession-->
    <!--       <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">-->
    <!--           &lt;!&ndash;只能使用构造器注入sqlSessionFactory,因为它没有set方法&ndash;&gt;-->
    <!--           <constructor-arg index="0" ref="sqlSessionFactory"/>-->
    <!--       </bean>-->

       </beans>
  3. 测试

Mybatis-spring

spring-dao.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: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/context
           https://www.springframework.org/schema/context/spring-context.xsd">
   
   
       <!--DataSource:使用Spring的数据源替换Mybatis的配置 c3p0 dbcp druid-->
       <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
           <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
           <property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&amp;useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false"/>
           <property name="username" value="root"/>
           <property name="password" value="12345678"/>
       </bean>
   
       <!--sqlSessionFactory-->
       <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
           <property name="dataSource" ref="dataSource"/>
           <!--绑定Mybatis配置文件-->
           <property name="configLocation" value="classpath:mybatis-config.xml"/>
           <property name="mapperLocations" value="classpath:com/lsq/dao/UserMapper.xml"/>
       </bean>
   
       <!--sqlSessionTemplate:就是我们是用的sqlSession-->
       <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
           <!--只能使用构造器注入sqlSessionFactory,因为它没有set方法-->
           <constructor-arg index="0" ref="sqlSessionFactory"/>
       </bean>
   
   </beans>  

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: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/context
       https://www.springframework.org/schema/context/spring-context.xsd">
   <import resource="spring-dao.xml"/>

   <bean id="userMapper" class="com.lsq.dao.UserMapperImpl">
       <property name="sqlSession" ref="sqlSession"/>
   </bean>
</beans>

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
       PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
       "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
   <properties resource="db.properties"/>

   <typeAliases>
       <package name="com.lsq.pojo"/>
   </typeAliases>
</configuration>
  1. 编写数据源配置

      <!--DataSource:使用Spring的数据源替换Mybatis的配置 c3p0 dbcp druid-->
           <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
               <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
               <property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&amp;useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false"/>
               <property name="username" value="root"/>
               <property name="password" value="12345678"/>
           </bean>
  2. sqlSessionFactory

     <!--sqlSessionFactory-->
           <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
               <property name="dataSource" ref="dataSource"/>
               <!--绑定Mybatis配置文件-->
               <property name="configLocation" value="classpath:mybatis-config.xml"/>
               <property name="mapperLocations" value="classpath:com/lsq/dao/UserMapper.xml"/>
           </bean>
  3. sqlSessionTemplate

     <!--sqlSessionTemplate:就是我们是用的sqlSession-->
           <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
               <!--只能使用构造器注入sqlSessionFactory,因为它没有set方法-->
               <constructor-arg index="0" ref="sqlSessionFactory"/>
           </bean>
  4. 需要给接口加实现类

    package com.lsq.dao;

    import com.lsq.pojo.User;
    import org.mybatis.spring.SqlSessionTemplate;

    import java.util.List;

    public class UserMapperImpl implements UserMapper{

       private SqlSessionTemplate sqlSession;

       public void setSqlSession(SqlSessionTemplate sqlSession) {
           this.sqlSession = sqlSession;
      }

       @Override
       public List<User> getUserList() {
           UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
           return userMapper.getUserList();
      }
    }
  5. 将自己写的实现类注入到Spring中

    <bean id="userMapper" class="com.lsq.dao.UserMapperImpl">
           <property name="sqlSession" ref="sqlSession"/>
    </bean>
  6. 测试使用

    import com.lsq.dao.UserMapper;
    import com.lsq.pojo.User;
    import org.junit.Test;
    import org.apache.ibatis.io.Resources;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;

    import java.io.IOException;
    import java.io.InputStream;
    import java.util.List;

    public class MyTest {
       @Test
       public void getUserList() throws IOException {
           ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
           UserMapper userMapper = context.getBean("userMapper", UserMapper.class);
           List<User> userList = userMapper.getUserList();
           for (User user : userList) {
               System.out.println(user);
          }
      }
    }

SqlSessionDaoSupport

spring-dao.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: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/context
           https://www.springframework.org/schema/context/spring-context.xsd">


       <!--DataSource:使用Spring的数据源替换Mybatis的配置 c3p0 dbcp druid-->
       <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
           <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
           <property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&amp;useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false"/>
           <property name="username" value="root"/>
           <property name="password" value="12345678"/>
       </bean>

       <!--sqlSessionFactory-->
       <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
           <property name="dataSource" ref="dataSource"/>
           <!--绑定Mybatis配置文件-->
           <property name="configLocation" value="classpath:mybatis-config.xml"/>
           <property name="mapperLocations" value="classpath:com/lsq/dao/UserMapper.xml"/>
       </bean>

       <!--sqlSessionTemplate:就是我们是用的sqlSession-->
<!--       <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">-->
<!--           &lt;!&ndash;只能使用构造器注入sqlSessionFactory,因为它没有set方法&ndash;&gt;-->
<!--           <constructor-arg index="0" ref="sqlSessionFactory"/>-->
<!--       </bean>-->

   </beans>

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">
   <import resource="spring-dao.xml"/>

<!--   <bean id="userMapper" class="com.lsq.dao.UserMapperImpl">-->
<!--       <property name="sqlSession" ref="sqlSession"/>-->
<!--   </bean>-->

   <bean id="userMapper2" class="com.lsq.dao.UserMapperImpl2">
       <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
   </bean>
</beans>

实现类

package com.lsq.dao;

import com.lsq.pojo.User;
import org.mybatis.spring.support.SqlSessionDaoSupport;

import java.util.List;

public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper {
   @Override
   public List<User> getUserList() {
       return  getSqlSession().getMapper(UserMapper.class).getUserList();
  }
}

测试

import com.lsq.dao.UserMapper;
import com.lsq.pojo.User;
import org.junit.Test;
import org.apache.ibatis.io.Resources;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class MyTest {
   @Test
   public void getUserList() throws IOException {
       ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
       UserMapper userMapper = context.getBean("userMapper2", UserMapper.class);
       List<User> userList = userMapper.getUserList();
       for (User user : userList) {
           System.out.println(user);
      }
  }
}

声明式事务

<!--配置声明式事务-->
   <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
       <property name="dataSource" ref="dataSource"/>
   </bean>

   <!--结合AOP实现事务的织入-->
   <!--配置事务的通知:-->
   <tx:advice id="txAdvice" transaction-manager="transactionManager">
       <!--给哪些方法配置事务-->
       <!--配置事务的传播特性:new propagation-->
       <tx:attributes>
           <tx:method name="add" propagation="REQUIRED"/>
           <tx:method name="delete" propagation="REQUIRED"/>
           <tx:method name="update" propagation="REQUIRED"/>
           <tx:method name="select" read-only="true"/>
           <tx:method name="*" propagation="REQUIRED"/>
       </tx:attributes>
   </tx:advice>

   <!--配置事务切入-->
   <aop:config>
       <aop:pointcut id="pointcut" expression="execution(* com.lsq.dao.*.*(..))"/>
       <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
   </aop:config>

标签:www,spring,Day20,springframework,context,org,import,public
From: https://www.cnblogs.com/happyQueen/p/17595283.html

相关文章

  • 【SpringBoot实现两级缓存】
    springboot中使用Caffeine+Redis实现二级缓存1.依赖准备首先确认Caffeine和redis这两者的依赖已导入(springboot版本为2.4.0):<!--redis与caffeine结合使用构成多级缓存--><dependency><groupId>org.springframework.boot</groupId><artifactId>sprin......
  • Eclipse转IDEA开发java项目spring+mybaits项目踩坑记录
    久了不用一个东西总有遗忘,记录是你快速找回状态之本。今天将原来eclipse写的spring+mybatisDemo在idea上跑起来,花了不少时间。这里将坑记录下:一、IDEA创建项目   1.IDEA中项目project等价于Eclipse中workspace, eclipse的workspace中可以创建多个工程;在IDEA中达到相......
  • vscode创建springboot项目
    1、安装ExtensionPackforjava2、安装jdk11环境sudoaptinstallopenjdk-11-jdk-headless3、在项目目录下创建src/main/java/com/example/app.javaimportorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplicat......
  • Spring IOC实现原理详解之IOC体系结构设计 : 关于bean的生成我自己的理解;
    1、系统根据bean的配置信息(xml文件,groovy等),经过资源加载、解析配置后生成了一个关于bean的容器。2、bean容器会根据配置信息生成一个bean实例;3、将bean实例 和 一些其他配置信息生成的一些特殊的bean实例 都放入到bean的容器中;4、其他的类需要调用这些bean的时候,根据申......
  • springboot前后端分离
    1、可以分两个软件来写springboot跟vue吗2、springboot可以前后端分离吗3、springboot国际化(前后端分离情况)4、jsp和springboot属于前后端不分离吗可以分两个软件来写springboot跟vue吗简述:Springboot+Vue前后端分离项目部署springboot前后端分离,主要采用docker容器部......
  • Caused by: java.lang.ClassNotFoundException: org.springframework.dao.support.Dao
    ​ 这个错误通常发生在缺少相关的依赖库或配置不正确时。根据错误信息,可以看出缺少了org.springframework.dao.support.DaoSupport类的定义。org.springframework.dao.support.DaoSupport是SpringFramework中的一个类,提供了对数据访问对象(DAO)的支持。这个错误通常发生在没有正......
  • Caused by: java.lang.ClassNotFoundException: org.springframework.dao.support.Dao
    ​ 这个错误通常发生在缺少相关的依赖库或配置不正确时。根据错误信息,可以看出缺少了org.springframework.dao.support.DaoSupport类的定义。org.springframework.dao.support.DaoSupport是SpringFramework中的一个类,提供了对数据访问对象(DAO)的支持。这个错误通常发生在没有正......
  • Caused by: java.lang.ClassNotFoundException: org.springframework.dao.support.Dao
     这个错误通常发生在缺少相关的依赖库或配置不正确时。根据错误信息,可以看出缺少了org.springframework.dao.support.DaoSupport类的定义。org.springframework.dao.support.DaoSupport是SpringFramework中的一个类,提供了对数据访问对象(DAO)的支持。这个错误通常发生在没有正确导......
  • Caused by: java.lang.ClassNotFoundException: org.springframework.dao.support.Dao
     这个错误通常发生在缺少相关的依赖库或配置不正确时。根据错误信息,可以看出缺少了org.springframework.dao.support.DaoSupport类的定义。org.springframework.dao.support.DaoSupport是SpringFramework中的一个类,提供了对数据访问对象(DAO)的支持。这个错误通常发生在没有正确导......
  • SpringMvc的执行流程及工作原理
     先上图针对流程图解析一下:用户发送请求至前端控制器DispatcherServlet前端控制器DispatcherServlet收到请求调用处理器映射器HandlerMapping。处理器映射器根据请求url找到具体的处理器,生成处理器执行链HandlerExecutionChain(包括处理器对象和处理器拦截器)一并返回给Dispa......