Spring5架构,万字文章带你学习

3.IOC操作Bean管理(基于xml)

1),什么是bean管理:

2),bean管理的实现方式:

a,基于xml配置文件的实现方式

1.基于XML方式创建对象

2.基于XML方式的属性注入

3.注入空值和特殊字符

4,注入bean

5.注入集合属性

6,Spring中的两种bean

7,bean的作用域:

8,XML的自动装配

9,引入外部属性管理

4.IOC操作Bean(基于注解)

1,spring针对创建对象提供的注解

2,开启组件扫面配置的细节配置

3,使用注解出入属性

​4,完全注解开发

三,Aop

1,什么是AOP

2,AOP的底层原理

1,AOP底层使用动态代理

2,使用JDK的动态代理

3,AOP中的相关术语

4,AOP的操作准备

5,AOP操作(AspectJ注解)

6,AOP操作(AspextJ注解)优化

7,AOP操作(XML配置文件)

8,完全注解开发

四,JdbcTemplate

1,JdbcTempalte的概念

2,使用JdbcTemplate模板对数据库的增删改查

​  3,使用JdbcTemplate模板对数据库的批量操作

五,事务操作

1,事务的概念:

2,事务环境的搭建

3,spring事务管理的介绍

1,事务添加到JavaEE的三层体系结构的Service层(业务逻辑层)

2,在Spring事务操作:

4,多事务之间事务的传播行为:

5, ioslation关于事务的隔离级别:

6,关于事务的超时限制:

7,readOnly是否只读:

8,rollbackFor:回滚

9,noRollbackFor:不回滚

10,事务完全注解开发




watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5L2Z5omv,size_20,color_FFFFFF,t_70,g_se,x_16

============================================================================================================================================================================================================================================================================================

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5L2Z5omv,size_20,color_FFFFFF,t_70,g_se,x_16

一.Spring框架概述

============

1,Spring是一个  开源的  轻量级的  JavaEE框架。


轻量级:体积小,jar独立使用不需要依赖其他jar包,

开源:免费,可以提供源代码

框架:解决开发的复杂性,简化企业开发。

2,spring的两个核心部分:IOC,Aop


IOC:控制反转,把创建对象的过程交给spring进行管理。

Aop:面向切面,在不修改源代码的情况下,进行功能的添加或增强。

3,spring框架的特点:


1),方便解耦,简化开发:对象与对象之间的关系依赖spring。

2),Aop编程支持:不改变源代码,增强功能

3),方便测试;

4),方便集成各种优秀框架。

5),方便进行食物管理,降低API的使用难度

6),java源码经典学习范例。

4,入门案例:


010752c1aa734b1ea55bf699ef763fa5.png

1),下载Spring5:

spring网址 : spring.io

直接下载地址:https://repo.spring.io/artifactory/plugins-release/org/springframework/spring/

还要下载一个日志jar包,spring5依赖于这个jar包commons-login这个jar

下载链接:commons-logging-1.1.1.jar下载及Maven、Gradle引入代码,pom文件及包内class -时代Java (nowjava.com)")

我个人下载5.2.6

fa987fa3413c494b98bf32d5f303f761.png

a3e3cee7a6f4479aba45ad07c30e0963.png

2),下载完成以后,参加一个普通的java项目,将jar导入项目

9228ed6528584fcfbeba1ff76e9e7ef3.png

3),使用spring

(1),创建普通类,在类中创建普通方法


public class User {

    public void add(){

        System.out.println("add.......");

    }

}

(2),创建spring配置文件,在配置文件中配置文件配置创建的对象

a,Spring配置文件使用xml文件配置

8d27cbdc3c8c4b1b9a6492b9f5caa9c3.png


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



    <!--配置User对象创建-->

    <bean id = "user" class = "com.yuge.User"></bean>

</beans>

b,创建测试类Test


public class Tset {



    @Test

    public void testAdd(){

        //1.读入上下文配置文件

        ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");

        //2.获取配置对象

        User user = context.getBean("user", User.class);



        System.out.println(user);

        user.add();

    }

}

c,测试结果,成功创建对象,并调用方法

70d09464ca7d49eeb9b6e5ec9d82d876.png

二,IOC容器

=======

1.IOC底层原理


1),什么是IOC:

控制反转,将对象的创建和对象之间的交互作用,都交给spring进行管理。

2),使用IOC的目的

为了降低耦合

3)IOC入门案例

2,IOC底层原理


1),xml解析,工厂模式,反射

2)图解IOC底层原理

传统方式:

4240640b79524479855961560b124b2f.png

工厂模式:

191feac52d964a08b3364ed05021f4fd.png

IOC模式:

7ca7606fce00452fad2160322cde0203.png

3.IOC接口(BeanFactory)


IOC基于容器完成,IOC容器的底层就是对象工厂

1),BeanFactory接口:

IOC容器的最基本实现,是spring内部的使用接口,不提倡给开发人员使用。

2),ApplicationContext接口:

是BeanFactory的子接口,提供比BeanFactory更强大的功能,一般为开发人员使用

3),两接口的区别

84a101f2318d40c882c6f143044e87c8.png

16259e0f328c48c48e2ec3d719d44368.png

因为我们在使用Spring框架时,一般都是配合网页使用,使用BeanFactory创建对象时,不会创建对象,而加载配置文件的时候,是在服务器启动的时候,使用tomcat,都是**将系统加载文件等费事非空间的事放在tomcat启动时完成,**以提供更好的用户体验,所以采用ApplicationContext接口

4),applicationContext的实现类

897a29a28edc4f58a804e9dfd48be5ba.png

3.IOC操作Bean管理(基于xml)


1),什么是bean管理:

**A,bean管理包括两个步骤:**Spring创建对象和Spring属性注入

2),bean管理的实现方式:

a,基于xml配置文件的实现方式


1.基于XML方式创建对象

378043c04f87444291ffb82732111625.png

id属性:给class类路径取个别名

class属性:创建对象类的全路径

XML方式创建默认对象默认使用空参构造器

2.基于XML方式的属性注入

(1),DI:依赖注入,就是注入属性。

DI与IOC的区别:DI是IOC的一种实现。

方式一:使用set方式注入

(a),创建类的对象,创建set方法

07fed5462c4d43cf9699e10c4732208a.png

(b),在配置文件中配置对象创建,配置属性注入

c025222b127d499c8225cc08dc48f128.png

方式二:使用有参构造方法注入

ae0b00d793f7466aad0f626babea2f4a.png

facc6f16fd144960b97743a3c4c4d134.png

方式三:p名称空间注入:

第一步:

14b78cae321143bbb7ac6b4d42c9650c.png

第二步:

39775d07a3f24029ad0475fb5252ca54.png

3.注入空值和特殊字符

一,注入空值

92ce7153c0cd47a19874aff91546c83d.png

e305795af14d4c15bc5d781607c52171.png

二,注入特殊符号

a3c20105276242e5a046e09471036ddb.png

4,注入bean

1),注入外部bean

引入外部bean,用service调用Dao层,就是引入外部bean的过程。

e3b621b271cf432789b38365f2656f1e.png

2)注入内部bean 和 级联赋值

a1d1283ad2a04a71a5118e171f07e3da.png

级联赋值方式1:不需要dept的get方法。

efb08a391fd34d29a9bb18e2f05a65f2.png

级联赋值方式2:第二种方法需要创建dept的get方法。

d54ef5a1ad674089bda4e7c19baea6f7.png

5.注入集合属性

0),创建Stu类,User类


package com.yuge;



import java.util.Arrays;

import java.util.List;

import java.util.Map;

import java.util.Set;



public class Stu {

    //数组类型

    private String course[];

    //List类型

    private List<String> name;

    //Map类型

    private Map<String,String> map;

    //Set类型

    private Set<String> set;

    //List类型中存入多个对象

    private List<User> userList;



    public void setUserList(List<User> userList) {

        this.userList = userList;

    }



    public void setCourse(String[] course) {

        this.course = course;

    }



    public void setName(List<String> name) {

        this.name = name;

    }



    public void setMap(Map<String, String> map) {

        this.map = map;

    }



    public void setSet(Set<String> set) {

        this.set = set;

    }



    public void show(){

        System.out.println(Arrays.toString(course));

        System.out.println(name);

        System.out.println(map);

        System.out.println(set);

        System.out.println(userList);

    }

}




package com.yuge;



public class User {

    private String name;



    public void setName(String name) {

        this.name = name;

    }



    public void add(){

        System.out.println("add.......");

    }



    @Override

    public String toString() {

        return "User{" +

                "name='" + name + '\'' +

                '}';

    }

}



1).XML注入数组类型属性

2),XML注入List集合属性

3),XML注入Map集合属性

4),XML注入Map属性

5),在集合中注入对象属性:


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

        xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd">



    <!--配置Stu对象创建-->

    <bean id="stu" class="com.yuge.Stu">

        <!--注入数组属性-->

        <property name="course">

            <array>

                <value>javaSe</value>

                <value>Mysql</value>

            </array>

        </property>

        <!--注入List对象-->

        <property name="name">

            <list>

                <value>武巴</value>

                <value>巴巴</value>

            </list>

        </property>

        <!--注入Map对象-->

        <property name="map">

            <map>

                <entry key="JAVASE" value="javase"></entry>

                <entry key="SPRING" value="Spring"></entry>

            </map>

        </property>

        <!--注入Set对象-->

        <property name="set">

            <set>

                <value>张三</value>

                <value>小三</value>

            </set>

        </property>

        <!--在list中注入对象属性-->

        <property name="userList">

            <list>

                <ref bean="user1"></ref>

                <bean id="user1=2" class="com.yuge.User">

                    <property name="name" value="李华"></property>

                </bean>

            </list>

        </property>

    </bean>

    <bean id="user1" class="com.yuge.User">

        <property name="name" value="李烨"></property>

    </bean>





</beans>

6),创建测试类


package com.yuge.test;



import com.yuge.Stu;

import com.yuge.User;

import org.junit.Test;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;



import java.applet.AppletContext;



public class Tset {



    @Test

    public void testAdd(){

        //加载配置文件

        ApplicationContext applicationContext =

                new ClassPathXmlApplicationContext("bean2.xml");

        //创建对象

        Stu stu = (Stu) applicationContext.getBean("stu");

        stu.show();

    }

}



7),输出结果

b9d663d9b29f4bf28a52359c6fc06613.png

8).将集合向上抽取为所有bean的公共集合

第一步:引入新的名称空间:

7eb38d078cd94ce491518226572eb0ae.png

第二步:使用util标签完成list集合注入的向上抽取

创建新的Book类测试向上抽取注入list


package com.yuge;



import com.sun.xml.internal.ws.api.model.wsdl.WSDLOutput;



import java.util.List;



public class Book {

    private List<String> bookList;



    public void setBookList(List<String> bookList) {

        this.bookList = bookList;

    }



    public void test(){

        System.out.println(bookList);

    }

}



配置XML文件抽取注入list的方法:


<?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:util="http://www.springframework.org/schema/util"

        xsi:schemaLocation=

                            "http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans.xsd

                            http://www.springframework.org/schema/util

http://www.springframework.org/schema/util/spring-util.xsd">

    <util:list id="list">

        <value>java从入门到入土</value>

        <value>python从入门到入狱</value>

    </util:list>

    <bean id="book" class="com.yuge.Book">

        <property name="bookList" ref="list"></property>

    </bean>

</beans>

运行结果:抽取成功

83e931d8f9e54fae9e6bf87718f5b7d6.png

抽取之前的样子:

893f605ebfd44ae8ae316f358aa9e639.png

抽取之后的样子:

e44c488e75164872af980fefa53c6d63.png

还可以抽取更多的对象。

3d8c1ffd30a845919b14d966d4993465.png

7d378da0e2dd4d4ab80ba0c53ba59211.png

6,Spring中的两种bean

1)普通bean:XML中定义什么类型就返回什么类型

2),工厂bean:XML中定义一个类型,可以返回其他类型

第一步:创建类作为工厂bean,实现FactoryBean的接口

第二步:实现接口里的方法,在实现的方法中定义返回的bean类型


package com.yuge.factoryBean;



import com.yuge.Stu;

import org.springframework.beans.factory.FactoryBean;



public class Mybean implements FactoryBean<Stu> {

    @Override

    public Stu getObject() throws Exception {

        Stu stu = new Stu();

        return stu;

    }



    @Override

    public Class<?> getObjectType() {

        return null;

    }



    @Override

    public boolean isSingleton() {

        return false;

    }

}



第三步:配置XML文件


    <bean id="myBean" class="com.yuge.factoryBean.Mybean">

    </bean>



测试:


    @Test

    public void testMyBean(){

        ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");

        Stu stu = context.getBean("myBean",Stu.class);

        System.out.println(stu);

    }

结果:

162edb242f5042d095b90653af6b1b8a.png

7,bean的作用域:

8de13ad4cc2c46268d201847fcc0ca52.png

在XML中配置bean时单实例还是多实例:

48316bb8ab7a49ad8668408e68121b2b.png

bf8d370dd7914834a9dc42bc5b9e9593.png

341e907edaf34931a520dba6c4c0bc2b.png

8,XML的自动装配

335bded283544e4ea16fa09cd093e8d7.png

自动装配:根据指定的装配规则,(属性名称或者属性类型),Spring自动将匹配的属性值填入。

演示自动自动装配:

1,根据名称装配

4dbf6458f2ac4a039599698e195d3c4e.png

2,根据属性类型装配

7ff0e97f4a4e48cebc01945937598c87.png

9,引入外部属性管理

1b03f5ce4d454b62b06f8b19c98523d6.png

a522022b892e46a69a5e272d00336444.png

bc0269a7824a418497495bc6e9b6921e.png

4.IOC操作Bean(基于注解)


1,spring针对创建对象提供的注解

第一步引入依赖:

567e48a57fab46199629a6202d963ae8.png

第二步:开启组件扫描

c9966bfbea904caeb15450dc03043dbf.png

第三步:创建类,在类上添加上注解。

1,@Component,都可以使用改注解创建对象

2a74e8dbe5274f47853a3e042b8e2b52.png

2,@Service,一般用于业务逻辑层,或者service层

3,@Controller,一般用于Web层

4,@Repository,一般用于Dao层

*上面的资格注解,功能都一样,只是将每个注解用于不同层便于开发人员区别。

2,开启组件扫面配置的细节配置


8bc4efb9887d4d2b977091a2b1aad163.png

793789032ae24ed8ad187203fea2c474.png

52277a95418f402c862dd3acc0d08bd6.png

3,使用注解出入属性

1),@Autowired:根据属性类型自动注入

第一步:使用注解在各个类中创建对象。

第二步:定义对象属性。在属性上面添加注解。不需要set方法。

6255901c6d31407a8cb6b1a670da8bf9.png

2),@Qualifier:根据属性名注入

770277417e8342a0a092c0c23405dcfd.png

3),@Resource:可以根据属性名和属性类型注入

f8b4a06ddfb34498a5c37231740c1726.png

*************以上三种是注入对象,不是普通类型**************

4),@Value:注入普通类型

c928177486bc4fad96211ddea4c743d7.png

4,完全注解开发

1),创建配置类,替代XML配置文件

298e8698e7f94ea1a3165e7aa52c493f.png

2),编写测试类

40477ea1ed5f46a7880ddd9a886db7f0.png

三,Aop

=====

面向切面,不修改源码对功能进行加强。

1,什么是AOP


对业务的各个逻辑进行隔离,从而使业务之间的逻辑耦合性降低,提高代码的可重用性,提高开发效率。

b1ffe98583d2435aa479e4abeed2698a.png

2,AOP的底层原理


1,AOP底层使用动态代理

1,有接口的动态代理,使用JDK的动态代理

创建接口的实现类的代理对象,增强类的方法

ec155db6e48645879ab4feeb09f70527.png

2,无接口的动态代理,使用CGLIB动态代理

创建子类的代理对象,增强类的方法

025a308d8288483dac9e9074294405b5.png

2,使用JDK的动态代理

使用proxy类实现动态代理

15607ac9a6c64c46b879e9b97e05ee77.png

4a2667ffd1a04fd9bc5cf8e14bb156c2.png

代码实现:

1,创建接口:


package com.JDK动态代理;



public interface UserDao {

    public int add(int a,int b);



    public String update(String id);

}

2,创建实现类


package com.JDK动态代理;



public class UserDaoImpl implements UserDao{

    @Override

    public int add(int a, int b) {

        return a+b;

    }



    @Override

    public String update(String id) {

        return id;

    }

}



3,使用proxy类创建接口的动态代理对象


package com.JDK动态代理;



import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.security.PublicKey;

import java.security.UnresolvedPermission;

import java.util.Arrays;



public class JDKProxy  {

    public static void main(String[] args) {

        Class[] interfaces = {UserDao.class};

        UserDao dao = (UserDao)Proxy.newProxyInstance(UserDaoProxy.class.getClassLoader(), interfaces, new UserDaoProxy(new UserDaoImpl()));

        int res = dao.add(1, 2);

        System.out.println(res);

    }

}



class UserDaoProxy implements InvocationHandler{



    //需要将待增强功能的类的对象传递到代理类中,并通过构造方法,代理类的构造方法将其实例化

    //通过UserDaoProxy创建UserDaoImpl的代理对象

    private Object obj;

    public UserDaoProxy(Object obj){

        this.obj = obj;

    }



    @Override

    /**

     *增加逻辑写在这个方法内

     * @ proxy:代理对象

     * @ method:需要增强的方法

     * @ args:要增强功能的方法需要的参数

     */

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        //方法之前

        System.out.println("方法之前执行。。。"+method.getName()+"传递的参数:"+ Arrays.toString(args));


### 最后

**对于很多Java工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。**

**整理的这些资料希望对Java开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。**

**再分享一波我的Java面试真题+视频学习详解+技能进阶书籍**

![美团二面惜败,我的凉经复盘(附学习笔记+面试整理+进阶书籍)](https://img-blog.csdnimg.cn/img_convert/d456c867232457c205e8eab660542707.webp?x-oss-process=image/format,png)


2,创建实现类



package com.JDK动态代理;

public class UserDaoImpl implements UserDao{

@Override

public int add(int a, int b) {

    return a+b;

}



@Override

public String update(String id) {

    return id;

}

}




3,使用proxy类创建接口的动态代理对象



package com.JDK动态代理;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.security.PublicKey;

import java.security.UnresolvedPermission;

import java.util.Arrays;

public class JDKProxy {

public static void main(String[] args) {

    Class[] interfaces = {UserDao.class};

    UserDao dao = (UserDao)Proxy.newProxyInstance(UserDaoProxy.class.getClassLoader(), interfaces, new UserDaoProxy(new UserDaoImpl()));

    int res = dao.add(1, 2);

    System.out.println(res);

}

}

class UserDaoProxy implements InvocationHandler{

//需要将待增强功能的类的对象传递到代理类中,并通过构造方法,代理类的构造方法将其实例化

//通过UserDaoProxy创建UserDaoImpl的代理对象

private Object obj;

public UserDaoProxy(Object obj){

    this.obj = obj;

}



@Override

/**

 *增加逻辑写在这个方法内

 * @ proxy:代理对象

 * @ method:需要增强的方法

 * @ args:要增强功能的方法需要的参数

 */

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

    //方法之前

    System.out.println("方法之前执行。。。"+method.getName()+"传递的参数:"+ Arrays.toString(args));

最后

对于很多Java工程师而言,想要提升技能,往往是自己摸索成长,不成体系的学习效果低效漫长且无助。

整理的这些资料希望对Java开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。

再分享一波我的Java面试真题+视频学习详解+技能进阶书籍

[外链图片转存中…(img-Y4SVd4tY-1714458637672)]

本文已被CODING开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码】收录

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值