欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring -从走火到入魔

程序员文章站 2022-07-05 11:06:47
项目管理框架,也是一套JAVAEE解决方案;优秀的设计模式组合;是一款将众多框架整合的产品...

一、概念

  • 项目管理框架,也是一套JAVAEE解决方案;
  • 优秀的设计模式组合;
  • 是一款将众多框架整合的产品

二、架构促成

  • 核心技术:依赖注入,事件,资源,验证,数据绑定,类型转换,I18N(i开头,N结尾,中间18个字符), SpEL(Spring表达式语言),AOP(面向切面编程);
  • 测试:模拟对象,TestContext框架,Spring MVC测试,WebTestClient。
  • 数据访问:事物,DAO,JDBC,ORM
  • 继承:远程处理,JMS,JCA,JMX,电子邮件,任务,调度,缓存。
  • 语言:Kotlin,Groovy,动态语言
    Spring -从走火到入魔
    Spring -从走火到入魔
    Spring -从走火到入魔

三、pom.xml配置

<?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>org.example</groupId>
    <artifactId>SpringTest</artifactId>
    <version>1.0-SNAPSHOT</version>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.6.RELEASE</version>
        </dependency>
    </dependencies>
</project>

四、(IOC &DI)控制反转&依赖注入:

bean节点:

  • id:指定bean的id,可以通过该id得到该bean的对象。
  • class:指明该类的路径,要求该bean类有 无参构造器。
  • scope:特指作用范围:
    1、singleton 单例模式(默认);
    2、prototype 多实例模式;
    3、request:web请求;
    4、session:web会话。

第一种(利用name):

poto实体:

@Data
public class User {
    private int uid;
    private String username;
    private String password;
    private int age;
    private String telephone;
    private Brand brand;
    
    public User() {
    }

    public User(int uid, String username, String password, int age, String telephone) {
        this.uid = uid;
        this.username = username;
        this.password = password;
        this.age = age;
        this.telephone = telephone;
    }

    public User(int uid, String username, String password, int age, String telephone, Brand brand) {
        this.uid = uid;
        this.username = username;
        this.password = password;
        this.age = age;
        this.telephone = telephone;
        this.brand = brand;
    }

    public int getUid() {
        return uid;
    }

    public void setUid(int uid) {
        this.uid = uid;
    }

    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;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getTelephone() {
        return telephone;
    }

    public void setTelephone(String telephone) {
        this.telephone = telephone;
    }

    public Brand getBrand() {
        return brand;
    }

    public void setBrand(Brand brand) {
        this.brand = brand;
    }

    @Override
    public String toString() {
        return "User{" +
                "uid=" + uid +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", age=" + age +
                ", telephone='" + telephone + '\'' +
                ", brand=" + brand +
                '}';
    }
}

beans.xml

<!--第一种 name-->
<bean id="user" class="pojo.User" scope="singleton">
    <property name="uid" value="1"/>
    <property name="username" value="明日花绮罗"/>
    <property name="password" value="123456"/>
    <property name="age" value="18"/>
    <property name="telephone" value="13355552222"/>
    <property name="brand" ref="brand"/>
</bean>
    <bean id="brand" class="pojo.Brand" scope="singleton">
        <constructor-arg name="bid" value="1"/>
        <constructor-arg name="bname" value="TokyoHot"/>
    </bean>

Test

 ApplicationContext applicationContext = new ClassPathXmlApplicationContext("Beans.xml");
        User user = applicationContext.getBean("user",User.class);
        System.out.println(user.toString());
        System.out.println();

Spring -从走火到入魔

  • bean
  • constructor-arg :调用带参构造器
  • property :调用Set方法
  • value:值
  • ref :引用

第二种(直接创建):

<!--第二种 直接赋值-->
    <bean id="user2" class="pojo.User">
        <constructor-arg value="2"/>
        <constructor-arg value="橘梨纱"/>
        <constructor-arg value="123456"/>
        <constructor-arg value="21"/>
        <constructor-arg value="15122223333"/>
        <property name="brand" ref="brand"/>
    </bean>

Spring -从走火到入魔

  • 代码简单
  • 可读性较差

第三种( 利用下标):

<!--第三种 按下标-->
    <bean id="user3" class="pojo.User">
        <constructor-arg index="0" value="3"/>
        <constructor-arg index="1" value="三上悠亚"/>
        <constructor-arg index="2" value="123456"/>
        <constructor-arg index="3" value="25"/>
        <constructor-arg index="4" value="15122312232"/>
        <property name="brand" ref="brand"/>
    </bean>

Spring -从走火到入魔


第四种(利用类型):

<!--第四种 按类型-->
    <bean id="user4" class="pojo.User">
        <constructor-arg type="java.lang.String" value="樱井莉亚"/>
        <constructor-arg type="int" value="4"/>
        <constructor-arg type="int" value="27"/>
        <constructor-arg type="java.lang.String" value="12345"/>
        <constructor-arg type="java.lang.String" value="15199987777"/>
        <property name="brand" ref="brand"/>
    </bean>

Spring -从走火到入魔

  • 相同类型 按先后顺序.

第五种(schema代理):

<?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:pp="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--   第五种: 代理-->
    <bean id="user5" class="pojo.User" pp:uid="5" pp:username="深田咏美" pp:password="12345" pp:age="25" pp:telephone="13533229988"/>
</beans>

Spring -从走火到入魔

  • 可读性较差

数组
实体类

package pojo;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Array {
    private String[] array;
    private List<Object> list;
    private Set<Integer> set;
    private Map<Object, Object> map;

    @Override
    public String toString() {
        return "Array{" +
                "array=" + Arrays.toString(array) +
                ", list=" + list +
                ", set=" + set +
                ", map=" + map +
                '}';
    }

    public String[] getArray() {
        return array;
    }

    public void setArray(String[] array) {
        this.array = array;
    }

    public List<Object> getList() {
        return list;
    }

    public void setList(List<Object> list) {
        this.list = list;
    }

    public Set<Integer> getSet() {
        return set;
    }

    public void setSet(Set<Integer> set) {
        this.set = set;
    }

    public Map<Object, Object> getMap() {
        return map;
    }

    public void setMap(Map<Object, Object> map) {
        this.map = map;
    }
}

ArrayBean.xml

<!--        数组节点:可以重复-->
        <property name="array">
            <array>
                <value>苍井空</value>
                <value>小泽玛利亚</value>
                <value>泷泽萝拉</value>
                <value>武藤兰</value>
                <value>麻美由真</value>
            </array>
        </property>

test

ackage Test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import pojo.Array;

public class TestArray {
    @Test
    public void test(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("ArrayBean.xml");
        Array array = applicationContext.getBean("array",Array.class);
        System.out.println(array.toString());
        System.out.println();
    }
}


集合

  • List 集合 (允许有重复)
<!--        list集合节点:可以重复-->
        <property name="list">
            <list>
                <value>东京热</value>
                <value>一本道</value>
                <value>加勒比</value>
            </list>
        </property>
  • set集合(不允许重复)

<!--        set集合节点:不能重复-->
        <property name="set">
            <set>
                <value>1000</value>
                <value>2000</value>
                <value>1000</value>
                <value>3000</value>
            </set>
        </property>
  • Map (允许value重复,不允许key重复)
   <property name="map">
            <map>
                <entry key="东京热" value="小泉彩"/>
                <entry key="加勒比"  value="樱空桃"/>
                <entry key="东京热" value="桥本有菜"/>
                <entry key="一本道" value="饭岛爱"/>
            </map>
        </property>

Spring -从走火到入魔


五、面向切面

基本概念
1、Aspect(切面):通常是一个类,里面可以定义切入点和通知。
2、JointPoint(连接点):程序执行过程中明确的点,一般是方法的调用。
3、Advice(通知):AOP在特定的切入点上执行的增强处理,有before,after,afterReturning,afterThrowing,around。
4、Pointcut(切入点):就是带有通知的连接点,在程序中主要体现为书写切入点表达式。
5、AOP代理:AOP框架创建的对象,代理就是目标对象的加强。Spring中的AOP代理可以使JDK动态代理,也可以是CGLIB代理,前者基于接口,后者基于子类。

五个通知方法
1、前置通知(before):在我们执行目标方法之前运行
2、后置通知(after):在我们目标方法运行结束之后 ,不管有没有异常
3、返回通知(AfterReturning):在我们的目标方法正常返回值后运行
4、异常通知(AfterThrowing):在我们的目标方法出现异常后运行
5、环绕通知(around):动态代理, 需要手动执行joinPoint.procced()(其实就是执行我们的目标方法执行之前相当于前置通知, 执行之后就相当于我们后置通知

*(AOP)实现方式

第一种 ( 使用Proxy的静态方法)

//实体类
package com.qfedu.aop01;

import lombok.Data;

@Data
public class User {

	private int uid;
	private String username;
	private String password;
	private String tel;
	private String addr;
}
//切面类
package com.qfedu.aop01;

public class MyAspect {

	public void before(){
		System.out.println("this is before");
	}

	public void after(){
		System.out.println("this is after");
	}
}

//业务
package com.qfedu.aop01;

import java.util.List;

public interface IUserService {

	List<User> getAllUsers();
	
	boolean saveUser(User u);

	boolean deleteUser(int uid);
}

//业务的实现
package com.qfedu.aop01;

import java.util.ArrayList;
import java.util.List;

public class UserServiceImpl implements IUserService {

	@Override
	public List<User> getAllUsers() {
		System.out.println("this is get all user method");
		return new ArrayList<>();
	}

	@Override
	public boolean saveUser(User u) {
		System.out.println("this is saveUser method");
		return false;
	}

	@Override
	public boolean deleteUser(int uid) {
		System.out.println("this is deleteUser method");
		return true;
	}

}

//
package com.qfedu.aop01;

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

public class UserServiceFactory {

	public static IUserService getUserService(){
		
		IUserService us = new UserServiceImpl();
		
		MyAspect ma = new MyAspect();
		

		return (IUserService) Proxy.newProxyInstance(UserServiceFactory.class.getClassLoader(), us.getClass().getInterfaces(), new InvocationHandler() {
			
		
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				
				//System.out.println("proxy " + proxy);
				System.out.println("method " + method);
				System.out.println("args " + args);
				ma.before();
				
				//	使用反射来调用每个方法原本应该调用的代码
				Object objs = method.invoke(us, args);
				
				//System.out.println("this is after");
				ma.after();
				
				return objs;
			}
		});
	}
}

1、 Proxy的静态方法newProxyInstance()包含三个参数:

  • 类的加载器
  • 接口们 us.getClass().getInterfaces();
  • InvocationHandler回调接口

2、invoke回调方法,包含三个参数:

  • proxy:被代理的对象
  • method: 被代理的对象中的所有的方法对象
  • args:被代理的对象中的所有的方法对象的参数列表

第二种(使用Spring里面的一个API对象Enhancer)

package com.qfedu.aop02;

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

public class UserServiceFactory {

	public static IUserService getUserService(){
		Enhancer eh = new Enhancer();
		
		eh.setSuperclass(IUserService.class);
		
		IUserService us = new UserServiceImpl();
		
		MyAspect ma = new MyAspect();
		
		eh.setCallback(new MethodInterceptor() {
			
			@Override
			public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
				
				ma.before();
				
				Object obj = arg1.invoke(us, arg2);
				
				ma.after();
				
				return obj;
			}
		});
		
		return (IUserService)eh.create();
	}
}

  1. 创建Enhancer增项类对象
  2. 设置增强类对象的superClass
  3. 设置Enhancer增强类对象的回调
  4. 通过Enhancer对象的create()方法得到指定的对象

第三种:

package Aop03;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class Aspect3 implements MethodInterceptor {

    public void before(){
        System.out.println("开始");
    }

    public void after(){
        System.out.println("结束");
    }


    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        before();
        Object object = methodInvocation.proceed();
        after();
        return object;
    }
}

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

    <bean id="us" class="Aop03.UserServiceImple3" />
    <bean id="ma" class="Aop03.Aspect3" />

    <!--
        ProxyFactoryBean代理的是FactoryBean,我们现在要做的事情是对于us实现代理
            该对象中包含了四个属性:
                target:目标对象,哪个对象将被以代理的方式创建
                interfaces:接口对象列表,注意使用的是value
                <list>
                    <value>com.qfedu.aop03.IUserService</value>
                    <value>com.qfedu.aop03.IUserService</value>
                    <value>com.qfedu.aop03.IUserService</value>
                </list>
                interceptorNames:拦截对象的名称,自定义的MyAspect类,实现了aopallianceb包下的MethodInterceptor接口,使用的是value
                optimize:boolean类型的值:
                    true:强制使用cglib的动态代理方式
                    false:使用JDK自带的动态代理方式

                    cglib:code generation library:代码生成仓库,效率相对于JDK的方式要更高一些
     -->
    <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <property name="target" ref="us" />
        <property name="interfaces" value="Aop03.UserService3" />
        <property name="interceptorNames" value="ma" />
        <property name="optimize" value="true"></property>
    </bean>
</beans>
    public  void test3(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("Aop03Bean.xml");
        UserService3 userService3 = applicationContext.getBean("proxy",UserService3.class);
        userService3.getAll();

    }


本文地址:https://blog.csdn.net/llp705/article/details/107458264

相关标签: mysql