Spring详解

Spring(春天)

优点:
1、Spring是一个开源免费的框架 , 容器 .
2、Spring是一个轻量级的框架 , 非侵入式的 .
3、控制反转 IoC , 面向切面 Aop
4、对事物的支持 , 对框架的支持
5、方便解耦,简化开发
Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架)。
组成
spring模块图

  • 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转(IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。

  • Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。

  • Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向切面的编程功能 , 集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理任何支持 AOP的对象。Spring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖组件,就可以将声明性事务管理集成到应用程序中。

  • Spring DAO:JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。

  • Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。

  • Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。

  • Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。

1、IOC基础

1、新建一个Maven项目
然后写一个我们原来的方式写的代码
1、先建一个UserDao接口

public interface UserDao {
    void getUser();
}

2、在写Dao的实现类

public class UserDaoImpl implements UserDao {
    public void getUser() {
        System.out.println("执行了该方法");
    }
}

3、然后去写UserService的接口

public interface UserService {
    void getUser();
}

4、写UserService的实现类

public class UserServiceImpl implements UserService{
    
     private UserDao userDao=new UserDaoImpl();
    public void getUser() {
        userDao.getUser();
    }
}

5、编写测试类

public void test(){
   UserService userService = new UserServiceImpl();
   service.getUser();
}

原本是这样写的,现在我们修改一下,把UserDao实现的类增加一个

public class StudentDaoImpl implements UserDao{
    public void getUser() {
        System.out.println("执行了学生的Dao");
    }
}

那么我们使用StudentDao的话,我们需要去service实现类里修改对应的实现

public class UserServiceImpl implements UserService{

    /* private UserDao userDao=new UserDaoImpl();*/
    private StudentDaoImpl studentDao=new StudentDaoImpl();
    public void getUser() {
        studentDao.getUser();
    }
}

假如我们在加一个Teacher的实现类。

public class TeacherImpl implements UserService {
    public void getUser() {
        System.out.println("执行了教师的方法");
    }
}

设想,想要测试这个类,又需要修改Service的代码

public class UserServiceImpl implements UserService{

    /* private UserDao userDao=new UserDaoImpl();*/
    /*private StudentDaoImpl studentDao=new StudentDaoImpl();*/
    private TeacherImpl teacher=new TeacherImpl();
    public void getUser() {
        teacher.getUser();
    }
}

这样每添加一个方法就要改动大量的代码,这种的耦合度太高,不适合设计思想,高内聚,低耦合。
我们有什么办法解决呢?
我们可以在需要用到他的地方 , 不去实现它 , 而是留出一个接口 , 利用set , 我们去代码里修改下 .

public class UserServiceImpl implements UserService{

    /* private UserDao userDao=new UserDaoImpl();*/
    /*private StudentDaoImpl studentDao=new StudentDaoImpl();*/
    /*private TeacherImpl teacher=new TeacherImpl();*/
    private UserDao userDao=new UserDaoImpl();
   //Set方法注入
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void getUser() {
        userDao.getUser();
    }
}

测试类里面

public class myTest {
    public static void main(String[] args) {
       UserService userService=new UserServiceImpl();
       ((UserServiceImpl) userService).setUserDao(new StudentDaoImpl());
       userService.getUser();
    }
}

我们不难发现这种方式,耦合度大大降低了,要调用不同的方法,不需要习惯Service的代码,只需要修改((UserServiceImpl) userService).setUserDao(new StudentDaoImpl());
以前所有的东西都是由程序去进行控制创建,而现在是由我们自行控制创建对象,把主动权由我们自行控制创建对象,交由调用者,程序不用去管是怎么去创建的,怎么实现的,它只负责提供一个接口

2、IOC容器

IOC又称依赖注入(DI),在此过程中,对象仅通过构造函数参数,工厂方法的参数或在构造或从工厂方法返回后在对象实例上设置的属性来定义其依赖项(即,与它们一起使用的其他对象) 。然后,容器在创建bean时注入那些依赖项。此过程从根本上讲是通过使用类的直接构造或诸如服务定位器模式之类的控件来控制其依赖项的实例化或位置的bean本身的逆过程(因此称为Control的倒置)。
Spring文档地址:
IOC实现流程图

3、Spring入门

1、导入Spring的Pom的pom依赖包

  <dependency>
             <groupId>org.springframework</groupId>
             <artifactId>spring-webmvc</artifactId>
             <version>5.2.0.RELEASE</version>
         </dependency>

2、编写代码
编写一个Hello实体类

public class Hello {
    String str;

    public String getStr() {
        return str;
    }

    public void setStr(String str) {
        this.str = str;
    }

    @Override
    public String toString() {
        return "Hello{" +
                "str='" + str + '\'' +
                '}';
    }
}
编写我们的spring文件 , 这里我们命名为applicationContectApplication.xml
xml表图
```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">
</beans>

向参数str里面注入值

<?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="hello" class="com.xiaohe.pojo.Hello">
    <property name="str" value="String"></property>
</bean>

</beans>

分析
-该id属性是标识单个bean定义的字符串。
-该class属性定义Bean的类型并使用完全限定的类名。
编写测试类(采用ClassPathXmlApplicationContext)

    @Test
  public  void test1(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Hello bean = context.getBean("hello",Hello.class);
        System.out.println(bean.getStr());
    }

注入成功 结果
思考
-Hello对象是谁创建的?
答:Spring创建的,即Xml中的就等同于创建对象的
-Hello对象的属性是怎么设置的?
hello对象的属性是由Spring容器设置的,这种方式叫做控制反转
-控制 : 谁来控制对象的创建 , 传统应用程序的对象是由程序本身控制创建的 , 使用Spring后 , 对象是由Spring来创建的
-反转 : 程序本身不创建对象 , 而变成被动的接收对象 .
依赖注入 : 就是利用set方法来进行注入的
修改上面的案例
将UserDaoImpl,TeacherDaoImpl,StudentDaoImpl,UserService交给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="StudentDaoImpl" class="com.xiaohe.dao.StudentDaoImpl"></bean>
   <bean id="TeacherImpl" class="com.xiaohe.dao.TeacherImpl"></bean>
   <bean id="UserServiceImpl" class="com.xiaohe.service.UserServiceImpl">
       <property name="userDao" ref="StudentDaoImpl"></property>
   </bean>
</beans>

测试方法

public class myTest {
    public static void main(String[] args) {
       ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserService userServiceImpl = context.getBean("UserServiceImpl",UserService.class);
        userServiceImpl.getUser();
    }
}

到了现在 , 我们彻底不用再程序中去改动了 , 要实现不同的操作 , 只需要在xml配置文件中进行修改 , 所谓的IoC,一句话搞定 : 对象由Spring 来创建 , 管理 , 装配 !

IOC创建对象的方法
1、通过无参构造方法创建
编写实体类

public class User {
    private String name;

    private int age;

    public User() {
        System.out.println("执行了无参构造");
    }

    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;
    }
    //定义一个方法
    public void show(){
        System.out.println("和振斌真好看啊");
    }
}

编写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="User" class="com.xiaohe.pojo.User">
        <property name="name" value="和振斌"/>
        <property name="age" value="23"/>
    </bean>

</beans>

编写测试类

public class myTest {
    @Test
    public void test1(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        User user = context.getBean("User",User.class);
        System.out.println(user.getAge());
        System.out.println(user.getName());
        user.show();
    }
}

执行效果图

我们发现在执行show()方法前,执行了无参构造,我们得知User对象通过无参构造初始化了
2、通过有参构造方法创建
创建实体类

public class UserT {
    private String name;

    private int age;

    public UserT(String name,int age) {
        this.name=name;
        this.age=age;
    }

    public String getName() {
        return name;
    }

     public UserT(String name,int age) {
        System.out.println("执行了有参构造");
        this.name=name;
        this.age=age;
    }
    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
    //定义一个方法
    public void show(){
        System.out.println("和振斌真好看啊");
    }
}

编写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="UserT" class="com.xiaohe.pojo.UserT">
        <constructor-arg index="0" value="和振斌"/>
        <constructor-arg index="1" value="23"/>
    </bean>

</beans>

测试

public class myTest {
    @Test
    public void test1(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext2.xml");
        UserT user = context.getBean("UserT",UserT.class);
        user.show();
    }
}

成功运行图

4、依赖注入(DI)

DI:
1、基于构造函数的依赖注入
2、基于Setter依赖注入

基于Setter依赖注入
要求被注入的属性 , 必须有set方法 , set方法的方法名由set + 属性首字母大写 , 如果属性是boolean类型 , 没有set方法 , 是 is .
测试pojo

public class Address {
    private String address;

    public String getAddress() {
        return address;
    }

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

    @Override
    public String toString() {
        return "address{" +
                "address='" + address + '\'' +
                '}';
    }
}

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;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Address getAddress() {
        return address;
    }

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

    public String[] getBooks() {
        return books;
    }

    public void setBooks(String[] books) {
        this.books = books;
    }

    public List<String> getHobbys() {
        return hobbys;
    }

    public void setHobbys(List<String> hobbys) {
        this.hobbys = hobbys;
    }

    public Map<String, String> getCard() {
        return card;
    }

    public void setCard(Map<String, String> card) {
        this.card = card;
    }

    public Set<String> getGames() {
        return games;
    }

    public void setGames(Set<String> games) {
        this.games = games;
    }

    public String getWife() {
        return wife;
    }

    public void setWife(String wife) {
        this.wife = wife;
    }

    public Properties getInfo() {
        return info;
    }

    public void setInfo(Properties info) {
        this.info = info;
    }


    @Override
    public String toString() {
        return "student{" +
                "name='" + name + '\'' +
                ", address=" + address +
                ", books=" + Arrays.toString(books) +
                ", hobbys=" + hobbys +
                ", card=" + card +
                ", games=" + games +
                ", wife='" + wife + '\'' +
                ", info=" + info +
                '}';
    }
}

编写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="address" class="com.xiaohe.pojo.Address">
        <property name="address" value="河南省汝州市"/>
    </bean>
    <bean id="student" class="com.xiaohe.pojo.Student">
        <property name="name" value="和振斌"/>
        <!--数组-->
        <property name="books">
            <array>
               <value>西游记</value>
               <value>水浒传</value>
               <value>三国演义</value>
            </array>
        </property>
        <property name="address" ref="address"/>
        <!--Map-->
        <property name="card">
            <map>
                <entry key="学号" value="201701014139"></entry>
                <entry key="身份证" value="1110555222"></entry>
            </map>
        </property>
        <!--Set集合-->
        <property name="games">
            <set>
                <value>LOL</value>
                <value>王者荣耀</value>
            </set>
        </property>
        <property name="hobbys">
            <list>
                <value>听歌</value>
                <value>打代码</value>
            </list>
        </property>
        <property name="info">
          <props>
              <prop key="学号">20555222</prop>
              <prop key="性别">男</prop>
              <prop key="姓名">小明</prop>
          </props>
        </property>
        <property name="wife"><null/></property>
    </bean>


</beans>

测试

public class myTest {
    @Test
    public void test1(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        Student student = context.getBean("student", Student.class);
        System.out.println(student.getAddress());
        System.out.println(student.getBooks());
        System.out.println(student.getGames());
    }
}

成功

5、Bean的自动装配

1、自动装配是使用spring满足bean依赖的一种方法

2、spring会在应用上下文中为某个bean寻找其依赖的bean

Spring中有三种Bean的装配机制,分别是:
1、在Xml中显性配置
2、在Java中显性配置
3、隐式的bean发现机制和自动装配
Spring的自动装配需要从两个角度来实现,或者说是两个操作:
组件扫描(component scanning):spring会自动发现应用上下文中所创建的bean;
自动装配(autowiring):spring自动满足bean之间的依赖,也就是我们说的IoC/DI;
组件扫描和自动装配组合发挥巨大威力,使得显示的配置降低到最少。

测试
1、新建一个项目
2、新建两个类,Cat、Dog都有一个go()方法

public class Cat {
    public void go(){
        System.out.println("狗叫");
    }
}

public class Dog {
    public void go(){
        System.out.println("狗叫");
    }
}

3、新建一个User实体类

public class User {
    private Dog dog;

    private Cat cat;

    private String name;

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    public void setName(String name) {
        this.name = name;
    }
}

4、编写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="dog" class="com.xiaohe.pojo.Dog"/>
    <bean id="cat" class="com.xiaohe.pojo.Cat"/>

    <bean id="user" class="com.xiaohe.pojo.User">
        <property name="cat" ref="cat" />
        <property name="dog" ref="dog"/>
    </bean>

</beans>

5、测试

    @Test
    public void test(){
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        User user = context.getBean("user", User.class);
        user.getDog().go();
        user.getCat().go();
    }

结果正常输出

自动装配
autowire byName (按名称自动装配)
由于在手动配置xml过程中,常常发生字母缺漏和大小写等错误,而无法对其进行检查,使得开发效率降低。
采用自动装配将避免这些错误,并且使配置简单化。
修改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="dog" class="com.xiaohe.pojo.Dog"/>
    <bean id="cat" class="com.xiaohe.pojo.Cat"/>

    <bean id="user" class="com.xiaohe.pojo.User" autowire="byName">
        <property name="name" value="和振斌"/>
    </bean>

</beans>

测试成功
注意ByName时,它是根据bean里面的id和Set后面的一致判断的
小结:
1、当一个bean节点带有 autowire byName的属性时。
2、将查找其类中所有的set方法名,例如setCat,获得将set去掉并且首字母小写的字符串,即cat。
3、去spring容器中寻找是否有此字符串名称id的对象。
4、如果有,就取出注入;如果没有,就报空指针异常。

byType
autowire byType (按类型自动装配)
修改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="dog" class="com.xiaohe.pojo.Dog"/>
    <bean id="cat" class="com.xiaohe.pojo.Cat"/>

    <bean id="user" class="com.xiaohe.pojo.User" autowire="byType">
        <property name="name" value="和振斌"/>
    </bean>

</beans>

使用autowire byType首先需要保证:同一类型的对象,在spring容器中唯一。如果不唯一,会报不唯一的异常。

注解
1、在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"
    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">


</beans>

2、开启属性注解支持!

<context:annotation-config/>

实体类变化

public class User {
    @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;
    }
}

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:annotation-config/>
    <bean id="dog" class="com.xiaohe.pojo.Dog"/>
    <bean id="cat" class="com.xiaohe.pojo.Cat"/>
    <bean id="user" class="com.xiaohe.pojo.User"/>
</beans>

测试成功

@Qualifier
1、@Autowired是根据类型自动装配的,加上@Qualifier则可以根据byName的方式自动装配
2、@Qualifier不能单独使用。
修改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:annotation-config/>
    <bean id="dog1" class="com.xiaohe.pojo.Dog"/>
    <bean id="cat3" class="com.xiaohe.pojo.Cat"/>
    <bean id="cat2" class="com.xiaohe.pojo.Cat"/>
    <bean id="user" class="com.xiaohe.pojo.User"/>
</beans>

测试直接报错

在属性上添加Qualifier注解

    @Autowired
    @Qualifier(value = "cat2")
    private Cat cat;

测试
成功

@Resource
1、@Resource如有指定的name属性,先按该属性进行byName方式查找装配;
2、其次再进行默认的byName方式进行装配;
3、如果以上都不成功,则按byType的方式自动装配。
都不成功,则报异常。

<?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/>
    <bean id="dog1" class="com.xiaohe.pojo.Dog"/>
    <bean id="cat3" class="com.xiaohe.pojo.Cat"/>
    <bean id="cat2" class="com.xiaohe.pojo.Cat"/>
    <bean id="user" class="com.xiaohe.pojo.User"/>



</beans>
public class User {
    @Resource
    private Dog dog;

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

报错,修改

public class User {
    @Resource(name = "dog1")
    private Dog dog;

    @Resource(name="cat2")
    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;
    }
}

小结
1、@Autowired与@Resource都可以用来装配bean。都可以写在字段上,或写在setter方法上。
2、@Autowired默认按类型装配(属于spring规范),默认情况下必须要求依赖对象必须存在,如果要允许null 值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用
3、@Resource(属于J2EE复返),默认按照名称进行装配,名称可以通过name属性进行指定。如果没有指定name属性,当注解写在字段上时,默认取字段名进行按照名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
它们的作用相同都是用注解方式注入对象,但执行顺序不同。@Autowired先byType,@Resource先byName。

使用注解开发
1、在配置文件当中,还得要引入一个context约束

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

</beans>

2、Bean的实现
1、配置文件中添加要扫描那些包下面的文件

  <context:component-scan base-package="com.xiaohe.pojo"/>

实体类写法

@Component("user")
// 相当于配置文件中 <bean id="user" class="当前注解的类"/>
public class User {
    @Value("和振斌")
// 相当于配置文件中 <property name="name" value="和振斌"/>
    private String name;

    @Value("18")
    private int age;

    public String getName() {
        return name;
    }


    public int getAge() {
        return age;
    }

}

测试方法

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

衍生注解
@Component三个衍生注解

为了更好的进行分层,Spring可以使用其它三个注解,功能一样,目前使用哪一个功能都一样。

-@Controller:web层

-@Service:service层

-@Repository:dao层

写上这些注解,就相当于将这个类交给Spring管理装配了!

基于JAVA类进行配置
实体类

@Component//交给spring管理
public class Dog {

    private String name="泰迪";

    public String getName() {
        return name;
    }
}

编写配置类

@Configuration //代表这是一个配置类
public class Myconfig {
    @Bean //通过方法注册一个bean,这里的返回值就Bean的类型,方法名就是bean的id!
    public Dog dog(){
      return new Dog();
    }
}

测试

  @Test
    public void test2(){
       ApplicationContext context = new AnnotationConfigApplicationContext(Myconfig.class);
        Dog dog = context.getBean("dog", Dog.class);
        System.out.println(dog.getName());
    }
}

成功

Aop

6、代理模式

1、静态代理
2、动态代理

静态代理(以租房为例)
Rent . java 即抽象角色

public interface Rent {
    public void rent();
}

Host . java 即真实角色

public class Host implements Rent {
    public void rent() {
        System.out.println("房主要租出房子");
    }
}

Proxy . java 即代理角色

//代理:中介
public class Proxy implements Rent {

    private Host host;

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

    //租房
    public void rent(){
        seeHouse();
        host.rent();
        fare();
    }
    //看房
    public void seeHouse(){
        System.out.println("带房客看房");
    }
    //收中介费
    public void fare(){
        System.out.println("收中介费");
    }
}

Client . java 即客户

public class Client {
    public static void main(String[] args) {
        //房东要租房
        Host host=new Host();
        //中介帮助房东
        Proxy proxy=new Proxy(host);
        //你去找中介
        proxy.rent();
    }
}

动态代理
···不太明白

posted @ 2020-12-27 10:39  池三岁  阅读(311)  评论(0编辑  收藏  举报