Spring

Spring

  1. 控制反转(IOC
  1. 之前,程序员是主动创建对象!控制权在程序员手上!
  2. 使用set注入后,程序不在具有主动性,而是变成了被动的接收对象!

(以前,假设创建一个Dao接口,有多个实现类实现了这个接口,之后再用service接口的实现类去调用,再由用户所需要的东西调用,但当用户要用不同的东西时,程序员需要在service的实现类中更换调用的Dao实现类才能满足用户的需求,现在,在service的实现类中加入set注入,就不需要单独的调用某一个Dao的方法,决定权到了用户的手里,用户放入什么东西,service看到东西在用那个对应的方法,由原先的service调用哪个方法就只能让用户使用哪个方法,到现在的用户要用什么,service看用什么在调用某个方法,这就是控制反转(IOC))

这种思想,从本质上解决了问题,我们程序员不用再去管理对象的创建了,系统的耦合性大大降低,可以更加专注的在一个业务的实现上,这就是IOC的原型!

  1. HelloSpring

正常写dao层接口实现类

正常写service层接口实现类

写spring的配置文件

<?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="Dao" class="com.cheng.dao.UserDaoImpl"/>
    <
bean id="mysql" class="com.cheng.dao.UserDaoMysqlImpl"/>

    <
bean id="UserServiceImpl" class="com.cheng.service.UserServiceImpl">
        <
property name="userDao" ref="mysql"/>
    </
bean>

   
<!--ref:引用Spring容器中创建好的对象
    value:具体的值,基本的数据类型!
-->



</beans>

测试

public class MyTest {

    public static void main(String[] args) {



        //获取ApplicationContext

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

        UserServiceImpl userServiceImpl = (UserServiceImpl) context.getBean("UserServiceImpl");

        userServiceImpl.getUser();





    }

}
  1. IOC创建对象的方式
  1. 使用无参构造创建对象,默认!
  2. 假设我们要使用有参构造创建方法。
  1. 下标赋值

<!--第一种,下标赋值!-->
<bean id="user" class="com.cheng.pojo.User">
    <
constructor-arg index="0" value="cheng"/>
</
bean>

  1. 第二种方式,通过类型创建(不建议使用)

<!--第二种方式,通过类型创建,不建议使用-->
<!--<bean id="user" class="com.cheng.pojo.User">-->
    <!--<constructor-arg type="java.lang.String" value="zheng"/>-->
<!--</bean>-->

  1. 第三种,直接通过参数名来设置

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

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

5spring配置

5.1、别名

别名,如果添加了别名,我们也可以使用别名获取到这个对象

<!--别名,如果添加了别名,我们也可以使用别名获取到这个对象-->
<alias name="user" alias="userNew"/>

5.2、Bean的配置

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

<bean id="userT" class="com.cheng.pojo.UserT" name="user2,u2">
    <
property name="name" value="cheng"/>
</
bean>

5.3、import

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

6、DI依赖注入

6.1、构造器注入

6.2、set方式注入【重点】

  1. 依赖注入:set注入!

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

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

【环境搭建】

  1. 复杂类型

public class Address {
      
private String address;

    public
String getAddress() {
       
return address;
   
}

   
public void setAddress(String address) {
       
this.address = address;
   
}
}

  1. 真实测试对象

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;

  1. 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.cheng.pojo.Student">
       
<!--第一种,普通值注入,value-->
       
<property name="name" value="cheng"/>
    </
bean>

</
beans>

  1. 测试类

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.getName());

   
}
}

完善注入信息

<?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.cheng.pojo.Address"/>

    <
bean id="student" class="com.cheng.pojo.Student">
       
<!--第一种,普通值注入,value-->
       
<property name="name" value="cheng"/>
       
<!--第二种,bean注入,ref-->
       
<property name="address" ref="address"/>
       
<!--第三种,数组注入-->
       
<property name="books">
            <
array>
                <
value>西游记</value>
                <
value>水浒传</value>
                <
value>三国演义</value>
            </
array>
        </
property>
       
<!--第四种,list注入-->
       
<property name="hobbys">
            <
list>
                <
value>听歌</value>
                <
value>跳舞</value>
                <
value>游泳</value>
            </
list>
        </
property>
       
<!--第五种,map注入-->
       
<property name="card">
            <
map>
                <
entry key="身份证" value="123456123456"/>
                <
entry key="英航卡" value="123456789467898"/>
            </
map>
        </
property>
       
<!--第六种,set注入-->
       
<property name="games">
            <
set>
                <
value>LOL</value>
                <
value>COC</value>
                <
value>BOB</value>
            </
set>
        </
property>
       
<!--第七种,NULL值注入-->
       
<property name="wife">
            <
null/>
        </
property>
       
<!--第八种,properties注入-->
       
<property name="info">
            <
props>
                <
prop key="学号">720188888</prop>
                <
prop key="性别"></prop>
            </
props>
        </
property>
    </
bean>

</
beans>

6.3、拓展方式

我们可以使用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.cheng.pojo.User" p:name="程" p:age="18"/>
   
<!--c命名空间注入,可以通过构造器注入:construct-args-->
   
<bean id="user2" class="com.cheng.pojo.User" c:age="18" c:name="cheng"/>
</
beans>

测试

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

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

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

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

6.4bean的作用域

Scope

Description

singleton

(Default) Scopes a single bean definition to a single object instance for each

 Spring IoC container.

prototype

Scopes a single bean definition to any number of object instances.

request

Scopes a single bean definition to the lifecycle of a single HTTP request.

 That is, each HTTP request has its own instance of a bean created off the

 back of a single bean definition. Only valid in the context of a web-aware

 Spring ApplicationContext.

session

Scopes a single bean definition to the lifecycle of an HTTP Session.

Only valid in the context of a web-aware Spring ApplicationContext.

application

Scopes a single bean definition to the lifecycle of a ServletContext.

Only valid in the context of a web-aware Spring ApplicationContext.

websocket

Scopes a single bean definition to the lifecycle of a WebSocket.

 Only valid in the context of a web-aware Spring ApplicationContext.

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

<bean id="user" class="com.cheng.pojo.User" p:name="程" p:age="18" scope="singleton"/>

  1. 原型模式(每次从容器中get的时候,都会产生一个新对象!)

<bean id="user" class="com.cheng.pojo.User" p:name="程" p:age="18" scope="prototype"/>

3.其余的request,session,appliaction这些只能在we吧开发中使用到

7、bean的自动装配

  1. 自动装配是Spring满足bean依赖的一种方式!
  2. Spring会在上下文中自动寻找,并自动给bean装配属性!

Spring中三种装配的方式

  1. 在xml中显示的装配
  2. 在java中显示配置
  3. 隐式的自动装配bean【重要】

7.1测试

1.环境搭配:一个人有两个宠物

7.2、ByName自动装配

<!--
byName:
会自动在容器上下文中查找,和自己对象set方法后面的值对应的值对应的beanid!
-->

<bean id="people" class="com.cheng.pojo.People" autowire="byName">
    <
property name="name" value="cheng"/>

</
bean>

7.3、ByType自动装配

<bean  class="com.cheng.pojo.Cat"/>
<
bean  class="com.cheng.pojo.Dog"/>

<!--
byName:
会自动在容器上下文中查找,和自己对象set方法后面的值对应的值对应的beanid!
byType:会自动在容器上下文中查找,和自己对象属性类型相同的beanid!
-->

<bean id="people" class="com.cheng.pojo.People" autowire="byType">
    <
property name="name" value="cheng"/>

小结:

  1. ByName的时候,需要保证所有bean的id唯一,并且这个bean需要和注入的属性的set方法的值一直!
  2. ByType的时候,需要保证所有bean的class唯一,并且这条个bean需要和自耦当注入的属性类型一致!

7.4、使用注解实现自动装配

要使用注解须知:

  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

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

@Resource与@Autowired功能相同,@Autowired不许导入spring,@Resource为java的

8、使用注解开发

1.bean        

@Component:组件,放在类上,说明这个类被spring管理了,就是bean!

2.属性如何注入

@Value("程"):放在定义属性上或在set方法上

3.衍生的注解

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

       Dao 【@Repository】

       Service【@Service】

       Controller【@Controller】

这四个注解功能一样的,都是将某个类注入到spring容器中,装配bean

4.自动装配置

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

@Resource与@Autowired功能相同,@Autowired不许导入spring,@Resource为java的

5.作用域

@Component

@Scope("prototype")

public class User {

    @Value("")

    public String name ;

}

6.小结

Xml与注解:

       Xml更加万能,适用于任何场合!维护简单方便

       注解,不是自己的类使用不了,维护相对复杂!

Xml与注解最佳实践:

       Xml用来管理bean;

       注解只负责完成属性的注入;

      

9、使用java的方式排配置spring

我们现在要完全不使用spring的xml配置了,全权交给java来做!

JavaConfig是spring的子项目

实体类

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 + '\'' +
               
'}';
   
}
}

配置文件

@Configuration
public class KuangConfig {

   
@Bean
   
public User getUser(){
       
return new User();
   
}
}

测试

public class MyTest {
   
public static void main(String[] args) {
       
ApplicationContext context = new AnnotationConfigApplicationContext(KuangConfig.class);
       
User getUser = (User) context.getBean("getUser");
       
System.out.println(getUser.getName());
   
}
}

10、代理模式

代理模式的分类:

  1. 静态代理
  2. 动态代理

10.1、静态代理

角色分析:

  1. 抽象角色:一般会使用接口或者抽象类来解决
  2. 真实角色:被代理的角色
  3. 代理角色:代理真实角色,代理真实角色后,我们一般会做一些附属操作
  4. 客户:访问代理对象的人

代码步骤:

  1. 接口
  2. //租房
    public interface Rent {
       
    public void rent();
    }
  3. 真实角色
  4. //房东
    public class Host implements Rent {

       
    public void rent() {
           
    System.out.println("房东要出租房子!");
       
    }
    }
  5. 代理角色
  6. public class Proxy implements Rent {
       
    private Host host;


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



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

       
    //看房
       
    public void seeHouse(){
           
    System.out.println("看房子");
       
    }


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


       
    //收中介费
       
    public void fare(){
           
    System.out.println("收中介费");
       
    }


    }
  7. 客户端访问代理角色
  8. public class Client {
       
    public static void main(String[] args) {
           
    Host host = new Host();
           
    Proxy proxy = new Proxy(host);
           
    proxy.rent();
       
    }
    }

代理模式的好处:

  1. 可以使真实角色的操作更加纯粹,不用去关注一些公共的业务!
  2. 公共也就交给代理角色!实现了业务的分工!
  3. 公共业务发生扩展的时候,方便集中管理!

缺点:

  1. 一个真实角色就会产生一个代理角色:代码量会翻倍,开发效率会变低

10.2动态代理

  1. 动态代理和静态代理角色一样
  2. 动态代理类是动态生成的,不是我们写好的
  3. 动态代理分为两大类,基于接口的动态代理,基于类的动态代理

基于接口实现---JDK动态代理

基于类实现—cglib

Java字节码实现:javassist

需要了解两个类:Proxy,InvocationHandler

InvocationHandler

11.3、使用spring实现Aop

导入依赖包

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->

<dependency>

    <groupId>org.aspectj</groupId>

    <artifactId>aspectjweaver</artifactId>

    <version>1.9.6</version>

</dependency>

方式一:用spring的api接口【主要SpringAPI接口实现】

方式二:自定义来实现AOP【主要是切面定义】

方式三:使用注解实现

12、整合Mybatis

步骤:
1.导入相关jar包

  1. Junit
  2. Mybatis
  3. Mysql数据库
  4. Spring相关的
  5. Aop植入
  6. Mybatis-spring[new]
  7. <!--junit-->
    <dependency>
        <
    groupId>junit</groupId>
        <
    artifactId>junit</artifactId>
        <
    version>4.12</version>
    </
    dependency>
    <!--mysql驱动-->
    <dependency>
        <
    groupId>mysql</groupId>
        <
    artifactId>mysql-connector-java</artifactId>
        <
    version>8.0.16</version>
    </
    dependency>
    <!--mybatis-->
    <dependency>
        <
    groupId>org.mybatis</groupId>
        <
    artifactId>mybatis</artifactId>
        <
    version>3.5.7</version>
    </
    dependency>
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
    <dependency>
        <
    groupId>org.springframework</groupId>
        <
    artifactId>spring-webmvc</artifactId>
        <
    version>5.3.13</version>
    </
    dependency>
    <!--Spring操作数据库的话,还需要一个spring-jdbc-->
    <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->

    <dependency>
        <
    groupId>org.springframework</groupId>
        <
    artifactId>spring-jdbc</artifactId>
        <
    version>5.3.14</version>
    </
    dependency>
    <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
    <dependency>
        <
    groupId>org.aspectj</groupId>
        <
    artifactId>aspectjweaver</artifactId>
        <
    version>1.9.6</version>
    </
    dependency>
    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
    <dependency>
        <
    groupId>org.mybatis</groupId>
        <
    artifactId>mybatis-spring</artifactId>
        <
    version>2.0.6</version>
    </
    dependency>

2.编写配置类

3.测试

12.1、回忆mybatis

1.编写实体类

2.编写核心配置文件

3.编写接口

4.编写Mapper.xml

5.测试

12.2mybatis-spring

1.编写数据源

2.sqlsessionfactory

3. SqlSessionTemplate

4.需要给接口加实现类

5.将自己写的实现类注入到spring中

6.测试

13、声明式事务

1、spring中的事务管理

  1. 声明式事务:AOP
  2. <!--配置声明式事务-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <
    constructor-arg ref="dataSource" />
    </
    bean>

    <!--结合AOP实现事务的织入-->
    <!--配置事务通知-->

    <tx:advice id="txAdvice" transaction-manager="transactionManager">
      
    <!--给哪些方法配置事务-->
        <!--配置事务的传播特性 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="txPointCut" expression="execution(* com.cheng.mapper.*.*(..))"/>
        <
    aop:advisor advice-ref="txAdvice" pointcut-ref="txPointCut"/>
    </
    aop:config>

  1. 编程式事务:需要在代码中,进行事务的管理

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值