2021-05-08

一、spring的简介
spring理念:是现有的技术更加容易使用,本身是一个大杂烩。
SSH:Struct2 + Spring + Hibernate
SSM: SpringMVC + Spring + Mybatis
  • spring是开源的免费的容器。
  • spring是一个轻量级的,非入侵式的。
  • 支持事务处理,对框架整合的支持。
  • 控制反转(IOC),面向切面编程 (AOP)。
总结:spring是一个轻量级的控制反转(IOC)和面向切面编程(AOP)的框架。
二、spring的使用
第一步:需要导入jar(Maven依赖)。
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-webmvc</artifactId>
    <version>5.2.0.RELEASE</version>
</dependency>
 
第二步:创建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="..." class="...">  
        <!-- collaborators and configuration for this bean go here -->
    </bean>
 
 
    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>
 
 
    <!-- more bean definitions go here -->
 
 
</beans>
三、spring ioc
概述:描述spring的ioc,简单来说就是帮我们创建bean(对象),让我们不用再创建对象。
3.1、bean创建
(1)使用无参构造创建bean
<bean id="address" class="com.kuang.pojo.Address"></bean>
  • id:是这个bean的唯一标注
  • class: 是类的权限定类名
(2)使用有参构造创建bean
<!--第一种方法:通过下标赋值创建-->
<bean id="user" class="com.kuang.pojo.User">
    <constructor-arg index="0" value="HollwWord"></constructor-arg>
</bean>
 
<!--第二种:通过类型创建,不建议使用-->
<bean id="user" class="com.kuang.pojo.User">
    <constructor-arg type="java.lang.String" value="HolleWord"></constructor-arg>
</bean>
 
<!--第三种:通过参数名来创建-->
<bean id="user" class="com.kuang.pojo.User">
    <constructor-arg name="name" value="琴江"></constructor-arg>
</bean>
 
3.2、bean作用域
<!--
    id : bean 的唯一标识符 使用getBean获取对象的参数
    class : bean对象的权限定名:包名+类型
    name : 也是别名,而且name可以取多个别名
-->
<bean id="user" class="com.kuang.pojo.User" name="newUser" scope="singleton">
    <constructor-arg name="name" value="琴江"></constructor-arg>
</bean>
<alias name="user" alias="newUser2"></alias>
 
 
<!--
    bean的作用域
    由bean的scope属性的值决定,默认是单例模式singleton
    值               说明
    singleton       单例模式
    prototype       原型模式
 
 
    单例模型:容器中只有一份实例,供所有人使用
    原型模式:每次从容器中get的时候,都会产生一个新对象
-->
 
3.3、bean的注入
  • bean的注入本质就是通过set方法进行注入,所有一定要有set方法否则会报错
第一种:普通值注入,value
<property name="name" value="张三"></property>
 
第二种:bean注入,ref
<bean id="address" class="com.kuang.pojo.Address">
    <property name="address" value="广东省茂名市信宜市"></property>
</bean>
 
<bean id="student" class="com.kuang.pojo.Student">
    <property name="address" ref="address"></property>
</bean>
第三种:数组注入
<bean id="student" class="com.kuang.pojo.Student">
   <property name="books">
        <array>
            <value>《鬼谷子》</value>
            <value>《狂神说》</value>
        </array>
    </property>
</bean>
 
第四种:List<T>集合注入
<property name="hobbys">
    <list value-type="java.lang.String">
        <value>打篮球</value>
        <value>打游戏</value>
        <value>看电视</value>
    </list>
</property>
 
第五种:Map<T,V>集合注入
<property name="card">
    <map >
        <entry key="身份证" value="486513486518756515"></entry>
        <entry key="学生证" value="0983109486"></entry>
    </map>
</property>
 
第六种:set<T>集合注入
<set>
    <value>LOL</value>
    <value>CF</value>
</set>
 
第七种:null值注入
<property name="wife">
    <null/>
</property>
 
第八种: Properties值注入
<property name="info">
    <props>
        <prop key="学号">0983109486</prop>
        <prop key="性别">男</prop>
    </props>
</property>
 
3.4、bean的自动装配
     (1) 通过bean标签的 autowire属性来设置。
  • byName :会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean(id 不区分大小写)
<bean id="people" class="com.kuang.pojo.People" autowire="byName">
    <property name="name" value="杨龙江"/>
</bean>
  • byType :会自动在容器上下文中查找,和自己对象属性相同的bean
<bean id="people1" class="com.kuang.pojo.People" autowire="byType">
    <property name="name" value="杨龙江"/>
</bean>
     (2) 通过注解来实现bean的自动装配
<!--
    使用注解进行装配要注意
    1、要先加入约束
     xmlns:context="http://www.springframework.org/schema/context"
     http://www.springframework.org/schema/context
     https://www.springframework.org/schema/context/spring-context.xsd"
    2、开启注解支持
     <context:annotation-config/>
 
     @Autowired
     直接在属性上使用即可!也可以在set方式上使用!
     使用@Autowired我们可以不用编写set方法,前提是你这个自动装配的属性在IOC(spring)容器中存在,且符合
     名字byName!
 
 
    如果@Autowired自动装配的环境比较复杂,自动装配无法通过一个注解【@Autowired】完成的时候,我们可以
    使用@Qualifier(value="xxx")
 
 
     @Resource这是一个java原生的注解,也可以实现自动装配
-->
 
public class People {
    @Autowired
    private Dog dog;
    @Autowired
    private Cat cat;
    private String name;
 
    public Dog getDog() {
        return dog;
    }
 
    public void setDog(Dog dog) {
        this.dog = dog;
    }
 
    public Cat getCat() {
        return cat;
    }
 
    public void setCat(Cat cat) {
        this.cat = cat;
    }
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
}
 
3.4、使用注解方式来创建bean
(1)功能:将该这个bean注册到spring的IOC容器中,等价于<bean id="user" class="com.kuang.pojo.User"></bean>(下面四个注解功能都一样)
  • @Controller           用在controller层
  • @Service                用在service层
  • @ Repository         用在mapper层
  • @Component        用在pojo层
(2)功能:设置这个bean的作用域
  • @Scope("xxxx")     prototype 原型模式     singleton 单例模式(默认)
(3)功能:给bean注入值     用法:放在属性上面,或者放在set方法上也可以
  • @Value("xxxx")   
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">
 
 
    <!--扫描指定包下的注解,这个包下的注解就会生效-->
    <context:component-scan base-package="com.kuang"/>
    <!--开启注解配置-->
    <context:annotation-config/>
</beans>
 
//@Component 等价于 <bean id="user" class="com.kuang.pojo.User"></bean>
//也就是直接在IOC容器中注册了User的bean
@Component
@Scope("prototype")
public class User {
    @Value("狂神")
    public String name="张三";
}
四、使用java的方式来配置spring
完全不使用xml文件。
准备一个cat的类。
@Component
public class Cat {
    @Value("cat")
    private String name;
    @Value("13")
    private int age;
 
 
    public String getName() {
        return name;
    }
 
 
    public void setName(String name) {
        this.name = name;
    }
 
 
    public int getAge() {
        return age;
    }
 
 
    public void setAge(int age) {
        this.age = age;
    }
 
 
    @Override
    public String toString() {
        return "Cat{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
然后创建一个spring的配置类。
//标志这个类被spring托管,这是一个配置类
@Configuration
//扫描该包下的注解
@ComponentScan("com.kuang.pojo")
//合并KuangConfig和KuangConfig2这两个配置类
@Import(KuangConfig2.class)
public class KuangConfig {
    //将这个类注册到spring容器中
    @Bean
    public User getUser(){
        return new User();
    }
 
 
    @Bean
    public Cat getCat(){
        return new Cat();
    }
}
测试
public class MyTest {
    @Test
    public void test1(){
        //如果完全使用java代码,脱离xml文件,需要用AnnotationConfigApplicationContext来读取配置类
        ApplicationContext context = new AnnotationConfigApplicationContext(KuangConfig.class);
        User user = (User)context.getBean("getUser");
        System.out.println(user.toString());
 
 
        Cat cat = (Cat)context.getBean("getCat");
        System.out.println(cat.toString());
    }
}
五、动态代理
1、准备一个接口
public interface Rent {
    //出租房子
    public void rent();
}
2、实现这个接口
public class Host implements Rent {
    public void rent() {
        System.out.println("房东要出租房子了!");
    }
}
3、创建一个类实现 InvoationHandler
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
 
 
//调用该类自动生成代理类!
public class ProxyInvocationHandler implements InvocationHandler {
    //被代理的接口
    private Rent rent;
 
    public void setRent(Rent rent) {
        this.rent = rent;
    }
 
    //生成得到代理类
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),rent.getClass().getInterfaces(),this);
    }
 
    //处理代理实例得到返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        seeHouse();
        //动态代理的本质,就是使用反射机制实现
        Object result = method.invoke(rent,args);
        fare();
        return null;
    }
 
    public void seeHouse(){
        System.out.println("中介带看房子");
    }
 
    public void fare(){
        System.out.println("收中介费");
    }
}
4、测试
public class Clicnt {
    public static void main(String[] args) {
        //真实角色
        Host host = new Host();
 
 
        //代理角色
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        //通过调用程序处理角色来处理我们要调用的接口对象!
        pih.setRent(host);
        Rent proxy = (Rent) pih.getProxy();
        proxy.rent();
    }
}
六、spring的AOP
使用aop需要到入aop的约束
public interface UserService {
    public String add();
    public void updata();
    public void delete();
    public void query();
}
 
public class UserServiceImpl implements UserService{
    public String add() {
        return "新增数据成功";
    }
 
 
    public void updata() {
        System.out.println("修改一条数据");
    }
 
 
    public void delete() {
        System.out.println("删除一条数据");
    }
 
 
    public void query() {
        System.out.println("查询一条数据");
    }
}
(1)使用原生的spring api接口
public class AfterLog implements AfterReturningAdvice {
    //AfterReturningAdvice 后置通知,代码执行后执行
    //returnValue 返回值
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("执行了"+method.getName()+"返回结果为:"+returnValue);
    }
}
 
public class Log implements MethodBeforeAdvice {
    //MethodBeforeAdvice 前置通知,执行之前执行
    //method 要执行的目标对象的方法
    //args 参数
    //target 目标对象
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println(target.getClass().getName()+"的"+method.getName()+"被执行了");
    }
}
 
<aop:config>
    <!--切入点:expression-->
    <aop:pointcut id="pointcut" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/>
 
    <!--执行环绕增加-->
    <aop:advisor advice-ref="log" pointcut-ref="pointcut"></aop:advisor>
    <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"></aop:advisor>
</aop:config>
 
(2)自定义类
public class DiyPointCut {
    public void before(){
        System.out.println("========方法执行前========");
    }
    public void after(){
        System.out.println("========方法执行后========");
    }
}
 
<bean id="diy" class="com.kuang.diy.DiyPointCut"></bean>
<aop:config>
    <!--自定义切面,ref 要引用的类-->
    <aop:aspect ref="diy">
        <!--切入点-->
        <aop:pointcut id="point" expression="execution(* com.kuang.service.UserServiceImpl.*(..))"/>
        <!--通知-->
        <aop:before method="before" pointcut-ref="point"/>
        <aop:after method="after" pointcut-ref="point"/>
    </aop:aspect>
</aop:config>
 
(3)通过注解实现AOP
需要导入aspectjrt包要不@Aspect会报红
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjrt</artifactId>
    <version>1.9.5</version>
</dependency>
 
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.kuang.service.*.*(..))")
    public void Before(){
        System.out.println("=======前置通知=========");
    }
 
    @After("execution(* com.kuang.service.*.*(..))")
    public void after(){
        System.out.println("=======后置通知=========");
    }
 
    //在环绕增强中,我们可以给定一个参数,代表我们要获取的切入点
    @Around("execution(* com.kuang.service.*.*(..))")
    public void around(ProceedingJoinPoint jp) throws Throwable {
        System.out.println("=======环绕前======");
        Signature signature = jp.getSignature();//获得签名
        System.out.println("准备执行"+signature.getName()+"方法");
        Object proceed = jp.proceed();//执行方法
        System.out.println("=======环绕后======");
    }
    /*springAOP的执行顺序
    * 1、执行这句代码 Object proceed = jp.proceed();前的方法
    * 2、执行前置通知
    * 3、执行方法
    * 4、执行这句代码 Object proceed = jp.proceed();后的方法
    * 5、执行后置通知
    * */
}
 
<!--通过注解实现Aop-->
<bean id="annotationPointCut" class="com.kuang.diy.AnnotationPointCut"></bean>
<!--开启Aop注解支持 JDK(默认 proxy-target-class="false") cglib(proxy-target-class="true")-->
<aop:aspectj-autoproxy proxy-target-class="true"/>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值