Spring在实际开发中的运用

    xiaoxiao2022-07-03  137

    文章目录

    一 Spring在实际开发中的运用1.1 什么是Spring1.2 导包 二 构造器注入2.1 根据下标进行引入2.2 根据名称进行引入2.3 根据类型进行引入2.4 自动进行引入2.5 在其它的bean的方式 三 属性注入3.1 普通属性3.2 集合3.3 数组与properties 四 XML的自动注入(了解即可)五 全注解(重要)5.1 扫描相应的包5.2 在相应的类上加注解5.3 如果出现多个bean类型一样怎么办? 六 代理模式(了解即可)七 Spring的AOP7.1 XML版本7.2 注解版

    一 Spring在实际开发中的运用

    1.1 什么是Spring

    轻量级的DI/IOC与AOP的容器框架!面试题:BeanFactory与ApplicationContext的区别?

    答:ApplicationContext是BeanFactory的子类,它拥有更加强大的一些方法(邮件,国际化,…),BeanFactory创建的Bean默认是懒加载,ApplicationContext是BeanFactory的子类是迫切加载!!!

    1.2 导包

    Spring需要的包

    <!--Spring的核心包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>4.2.5.RELEASE</version> </dependency> <!--Context包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.2.5.RELEASE</version> </dependency> <!--aop的包--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>4.2.5.RELEASE</version> </dependency> <!--切面的一个包(织入)--> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.8</version> </dependency> <!-- Spring的测试包 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.2.5.RELEASE</version> <!--scope:范围,只能在test包中使用--> <scope>test</scope> </dependency> <!--junit的测试支持--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency>

    引入一些插件与资源

    需要去读到java中的xml文件(默认不会编译) <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> </configuration> </plugin> </plugins> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <resource> <directory>src/test/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> </build>

    二 构造器注入

    标签: constructor-arg属性 index/name/type = 下标/名称/类型属性 value/ref = 普通的值/引用

    2.1 根据下标进行引入

    <bean id="myBean" class="wltyx.nyybw._02_constructor.MyBean"> <constructor-arg index="0" value="小莫" /> <constructor-arg index="1" value="99" /> </bean>

    2.2 根据名称进行引入

    <bean id="myBean" class="wltyx.nyybw._02_constructor.MyBean"> <constructor-arg name="name" value="小莫" /> <constructor-arg name="age" value="99" /> </bean>

    2.3 根据类型进行引入

    不能出现重复类型

    <bean id="myBean" class="wltyx.nyybw._02_constructor.MyBean"> <constructor-arg type="java.lang.String" value="小莫" /> <constructor-arg type="java.lang.Integer" value="99" /> </bean>

    2.4 自动进行引入

    顺序是不允许修改的

    <bean id="myBean" class="wltyx.nyybw._02_constructor.MyBean"> <constructor-arg value="小莫" /> <constructor-arg value="99" /> </bean>

    2.5 在其它的bean的方式

    外部bean是可以重复使用

    <bean id="otherBean" class="wltyx.nyybw._02_constructor.OtherBean"> </bean> <bean id="myBean" class="wltyx.nyybw._02_constructor.MyBean"> <!-- 外部bean --> <constructor-arg index=0 ref="otherBean" /> <!-- 内部bean --> <constructor-arg index="2"> <bean class="wltyx.nyybw._02_constructor.OtherBean" /> </constructor-arg> </bean>

    三 属性注入

    3.1 普通属性

    准备属性

    // 简单属性 private Long id; private String name; private Boolean sex; private BigDecimal salary;

    配置的代码

    <property name="id" value="1" /> <property name="name" value="王霸天" /> <property name="sex" value="true"/> <property name="salary" value="58" />

    3.2 集合

    准备的属性

    list与set(不允许重复)关键的那个标签(list,set,array)写错也可以用(但是不建议) private List<String> list; private Set<String> set; private List<OtherBean> otherBeanList; private Set<OtherBean> otherBeanSet;

    配置的代码

    <property name="list"> <list> <value>abc</value> <value>abc</value> <value>123</value> <value>321</value> </list> </property> <!--Set<String> set :无序,不重复--> <property name="set"> <set> <value>abc</value> <value>abc</value> <value>123</value> <value>321</value> </set> </property> <!--List<OtherBean> otherBeanList--> <property name="otherBeanList"> <list> <ref bean="otherBean" /> <ref bean="otherBean" /> <bean class="wltyx.nyybw._03_di.OtherBean" /> <bean class="wltyx.nyybw._03_di.OtherBean" /> </list> </property> <!--Set<OtherBean> otherBeanSet--> <property name="otherBeanSet"> <set> <ref bean="otherBean" /> <ref bean="otherBean" /> <bean class="wltyx.nyybw._03_di.OtherBean" /> <bean class="wltyx.nyybw._03_di.OtherBean" /> </set> </property>

    3.3 数组与properties

    数组与properties都有两种写法(简写形式)properties的简写形式不支持中文

    数组与properties

    private String[] arrays; private Properties props1; private Properties props2;

    xml配置

    <!--String[] arrays :标准写法 --> <!-- <property name="arrays"> <array> <value>abc</value> <value>def</value> <value>gf</value> </array> </property> --> <!--String[] arrays :简写形式 (数组中每个值用,隔开)--> <property name="arrays" value="abc,dfe,fd" /> <!--Properties props1:标准写法--> <property name="props1"> <props> <prop key="driver">com.mysql.jdbc.Driver</prop> <prop key="url">jdbc:mysql:///spring哈哈</prop> <prop key="username">root</prop> <prop key="password">admin</prop> </props> </property> <!--Properties props2:简写形式(不支持中文)--> <property name="props2"> <value> driver=com.mysql.jdbc.Driver url=jdbc:mysql:///spring哈哈 username=root </value> </property>

    四 XML的自动注入(了解即可)

    自动注入有两种方式 (类型与名称)设置全局的自动注入 <beans ... default-autowire="byType/byName">单独为某一个bean配置自动注入 <bean ... autowire="byType/byName">

    五 全注解(重要)

    5.1 扫描相应的包

    注意:引入context的头 <context:component-scan base-package="wltyx.nyybw._05_anno" />

    5.2 在相应的类上加注解

    Controller:控制层

    Service:业务层

    Repository:持久层

    Component:组件(一个bean不知道在哪一层用这个)

    @Autowired:注入功能

    5.3 如果出现多个bean类型一样怎么办?

    注解的bean有默认名称(类名【首字母小写】) 如 userDaoImpl修改bean的名称 Component/Service/Repository/Controller("名称")在注入bean的时候加上一个限定注解 @Autowired @Qualifier("userJPADaoImpl") //@Resource(name = "userJDBCDao") private IUserDao userDao;

    六 代理模式(了解即可)

    分为静态与动态Spring使用的是动态代码:JDK(接口)/CGLIB动态代理的代码 //通过JDK的方案创建一个动态代理对象呢? /** * java.lang.reflect:Proxy(代理)对象 * Foo Bar:张三,李四,王五 * ClassLoader loader :类加载器(随便给它一个) Class<?>[] interfaces:接口(为什么这里是一个数组) InvocationHandler h :增强功能(自己实现) */ IEmployeeService proxy = (IEmployeeService)Proxy.newProxyInstance( this.getClass().getClassLoader(), employeeService.getClass().getInterfaces(), new InvocationHandler() { /** * @param proxy :代理对象(没有用) * @param method :执行的方法 * @param args :方法中的参数 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; try { txManager.begin(); //在这里面完成功能增强 //通过反射执行相应的方法 result = method.invoke(employeeService, args); txManager.commit(); } catch (Exception e) { txManager.rollback(); e.printStackTrace(); } finally { txManager.close(); } return result; } });

    七 Spring的AOP

    7.1 XML版本

    准备接口:IEmployeeService

    public interface IEmployeeService { void save(); void update(); void delete(); }

    准备实现 EmployeeServiceImpl

    public class EmployeeServiceImpl implements IEmployeeService { @Override public void save() { System.out.println("送花给你...."); } @Override public void update() { System.out.println("EmployeeServiceImpl udpate.."); } @Override public void delete() { System.out.println("EmployeeServiceImpl delete.."); //int i = 1/0; } }

    事务管理器(假)

    public class TxManager { public void begin(){ System.out.println("开启事务..."); } public void commit(){ System.out.println("提交事务..."); } public void rollback(Throwable e){ System.out.println("回滚事务...,错误的原因:"+e.getMessage()); } public void close(){ System.out.println("关闭资源..."); } //搞了一个ProceedingJoinPoint(连接点对象) public void around(ProceedingJoinPoint joinPoint){ System.out.println(joinPoint.getArgs()); //参数 System.out.println(joinPoint.getSignature()); //方法签名(这个方法的所有信息) System.out.println(joinPoint.getTarget().getClass()); //真实主题角色 System.out.println(joinPoint.getThis().getClass()); //代理主题角色 try { begin(); joinPoint.proceed(); //执行对应的方法 commit(); } catch (Throwable e) { rollback(e); e.printStackTrace(); } finally { close(); } } }

    配置(关键)

    引入aop的头准备两个bean(EmployeeServiceImpl,TxManager)如果有环绕通知,其它通知就不需要了注意:何时,何地,做什么 <?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 http://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="employeeService" class="wltyx.nyybw._08_xmlaop.EmployeeServiceImpl" /> <!--准备一个事务--> <bean id="txManager" class="wltyx.nyybw._08_xmlaop.TxManager" /> <!--何时,何地,做什么事--> <!--代表要做一个AOP的配置--> <aop:config> <!-- 配置(定义)切点 在哪些类的哪些方法进行功能 id:切点名称(随便取) expression:表达式(最后定位都是方法) *:所有返回值 wltyx.nyybw._08_xmlaop:对应的包 I*Service:以I开头,Service结尾的所有接口(所有实现接口的方法) *:所有方法 (..):所有参数 --> <aop:pointcut id="pointcut" expression="execution(* wltyx.nyybw._08_xmlaop.I*Service.*(..))" /> <!-- 切面:由切点和增强组成 ref="txManager" -> 对应的增强类 --> <aop:aspect ref="txManager"> <!-- aop:before:前置通知 何地:在哪些类的哪些方法中:pointcut 何时:在方法执行之前:before 做什么事:执行txManager这个bean中的begin方法 try { //前置通知 result = method.invoke(employeeService, args); //后置通知 } catch (Exception e) { //异常通知 } finally { //最终通知 } --> <!--<aop:before method="begin" pointcut-ref="pointcut" />--> <!--后置通知--> <!--<aop:after-returning method="commit" pointcut-ref="pointcut" />--> <!--异常通知 throwing这个错,方法中才可以获到(名字必需一致) --> <!--<aop:after-throwing method="rollback" pointcut-ref="pointcut" throwing="e" />--> <!--最终通知 --> <!--<aop:after method="close" pointcut-ref="pointcut" />--> <!--环绕通知--> <aop:around method="around" pointcut-ref="pointcut" /> </aop:aspect> </aop:config> </beans>

    测试

    查看一下这个对象是否已经被代理声明必需是接口测试一下有异常与没有异常的区别

    7.2 注解版

    需要在相应的bean上加注解配置包的扫描所有的配置都是在TxManager加注解

    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" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd "> <!--扫描包--> <context:component-scan base-package="wltyx.nyybw._09_annoaop" /> <!--支持切面的注解--> <aop:aspectj-autoproxy /> </beans>

    TxManager

    切点的名字是方法名() package wltyx.nyybw._09_annoaop; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; /** * @Aspect -> <aop:aspect ref="txManager"> */ @Component @Aspect public class TxManager { /** * 切点: * <aop:pointcut id="pointcut()" expression="execution(* wltyx.nyybw._09_annoaop.I*Service.*(..))" /> */ @Pointcut("execution(* wltyx.nyybw._09_annoaop.I*Service.*(..))") public void pointcut(){} // @Before("pointcut()") public void begin(){ System.out.println("开启事务..."); } // @AfterReturning("pointcut()") public void commit(){ System.out.println("提交事务..."); } // @AfterThrowing(pointcut = "pointcut()",throwing = "e") public void rollback(Throwable e){ System.out.println("回滚事务...,错误的原因:"+e.getMessage()); } // @After("pointcut()") public void close(){ System.out.println("关闭资源..."); } //搞了一个ProceedingJoinPoint(连接点对象) @Around("pointcut()") public void around(ProceedingJoinPoint joinPoint){ System.out.println(joinPoint.getArgs()); //参数 System.out.println(joinPoint.getSignature()); //方法签名(这个方法的所有信息) System.out.println(joinPoint.getTarget().getClass()); //真实主题角色 System.out.println(joinPoint.getThis().getClass()); //代理主题角色 try { begin(); joinPoint.proceed(); //执行对应的方法 commit(); } catch (Throwable e) { rollback(e); e.printStackTrace(); } finally { close(); } } }
    最新回复(0)