Spring基础-02

Spring基础-02

1.Spring注解开发

  1. 开启注解配置,并配置要扫描的包。
<?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/>
    <!-- 配置要扫描的包 -->
    <context:component-scan base-package="com.my.domain"/>
    
</beans>
  1. 注解配置。
    1. @Component将bean注入到容器。同作用的注解还有@Controller、@Service、@Repository。
    2. @Scope配置bean的作用域。
    3. @Value可以作用在属性和方法中,为属性注入值。
    4. @Autowired、@Qualifier、@Resource,自动装配。
@Component
@Scope(scopeName = "singleton")
public class Person {

    @Value("bob")
    private String name;

    @Value("tom") //可以作用在方法上
    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

2.Java代码配置Spring容器

  1. 配置Spring容器。
    1. @Configuration,声明为一个配置类。
    2. @Component,将bean注入容器。
    3. @Import,导入更多的配置类。
    4. @Bean,将返回的bean注入容器。
    5. @ComponentScan,配置要扫描的包。
    6. @Order,多个配置文件时,定义加载配置文件的顺序。
@Configuration
@Component
@Import(AspectConfig.class) //@Import 对于多个配置类,可以使用@Import来引入
public class SpringConfig {

    //@Bean 默认使用方法名作为bean的id。可以使用name、value修改bean的id。
    @Bean(name = "person")
    public Person getPerson() {
        return new Person();
    }
}

public class AspectConfig {
}
  1. 启动Spring容器,使用AnnotationConfigApplicationContext。
public class UserTest {

    @Test
    public void test01() {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        Person person = context.getBean("person", Person.class);
        System.out.println(person.getName());
    }
}

3.静态代理

  1. 被代理对象。
public interface ISport {

    void sport();
}

public class SportImpl implements ISport {

    @Override
    public void sport() {
        System.out.println("sport");
    }
}
  1. 代理对象。
public class ProxySport implements ISport{

    private ISport sport;

    public ProxySport(ISport sport) {
        this.sport = sport;
    }


    @Override
    public void sport() {
        System.out.println("=====start=====");
        sport.sport();
        System.out.println("=====end=====");
    }
}
  1. 客户端。
public class Client {

    public static void main(String[] args) {
        SportImpl sport = new SportImpl();
        ProxySport proxySport = new ProxySport(sport);
        proxySport.sport();
    }
}
  1. 缺点。增加功能时需要修改原有代码;并且增加一个功能,代码量翻倍,原有类和代理类有需要实现这个方法。

4.动态代理

  1. 被代理对象。
public interface ISport {

    void sport();
}

public class SportImpl implements ISport {

    @Override
    public void sport() {
        System.out.println("sport");
    }
}
  1. 代理对象
public class SportProxy implements InvocationHandler {
    private ISport sport;

    public SportProxy(ISport sport) {
        this.sport = sport;
    }

    public ISport getInstance() {
        ISport sportProxy = (ISport) Proxy.newProxyInstance(this.getClass().getClassLoader(),
                sport.getClass().getInterfaces(), this);
        return sportProxy;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("日志记录");
        method.invoke(sport, args);
        return proxy;
    }
}
  1. 客户端
public class Client {

    public static void main(String[] args) {
        SportImpl sport = new SportImpl();
        SportProxy proxy = new SportProxy(sport);
        
        ISport proxySport = proxy.getInstance();
        proxySport.sport();
    }
}
  1. 优点。Java自动生成代理对象;对于像日志打印等功能,被代理对象功能增加了,但是代理对象SportProxy的invoke方法依然不变,只需要记录日志即可。
  2. 动态代理的实现方式。JDK动态代理,基于接口;cglib,基于类的动态代理。

5.Spring AOP

  1. 需要引入的依赖
<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.8</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.7</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.1</version>
        <scope>test</scope>
    </dependency>
</dependencies>
  1. Spring AOP,使用Spring API实现。

    1. 实体业务类。
    public interface IUserService {
    
        void add();
    }
    
    public class UserService implements IUserService{
        @Override
        public void add() {
            System.out.println("add=====");
        }
    }
    
    1. 通知类。
    public class AfterLog implements AfterReturningAdvice {
        @Override
        public void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {
            System.out.println("执行完成");
        }
    }
    
    public class BeforeLog implements MethodBeforeAdvice {
    
    
        @Override
        public void before(Method method, Object[] objects, Object o) throws Throwable {
            System.out.println("开始运行");
        }
    }
    
    1. 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:aop="http://www.springframework.org/schema/aop"
           xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
    
        <bean id="userService" class="com.my.UserService" />
        <bean id="beforeLog" class="com.my.BeforeLog" />
        <bean id="afterLog" class="com.my.AfterLog" />
        
        <aop:config>
            <!-- 切入点 -->
            <aop:pointcut id="pointcut" expression="execution(* com.my.*.*(..))"/>
            <!-- 通知 -->
            <aop:advisor advice-ref="beforeLog" pointcut-ref="pointcut" />
            <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut" />
        </aop:config>
    </beans>
    
  2. Spring AOP,配置文件实现。

    1. 切面类。
    public class Log {
    
        public void before() {
            System.out.println("=====before=====");
        }
    
        public void after() {
            System.out.println("=====after=====");
        }
    }
    
    1. 配置文件。
    <?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
            https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
    
        <bean id="userService" class="com.my.UserService" />
        
        <bean id="log" class="com.my.Log"/>
        <aop:config>
            <!-- 切面 -->
            <aop:aspect id="aspect" ref="log">
                <!-- 切入点 -->
                <aop:pointcut id="pointcut" expression="execution(* com.my.*.*(..))"/>
    
                <!-- 通知 -->
                <aop:before method="before" pointcut-ref="pointcut" />
                <aop:after method="after" pointcut-ref="pointcut" />
            </aop:aspect>
        </aop:config>
    </beans>
    
  3. Spring AOP,注解实现。

    1. 切面。
    @Aspect
    public class LogAspect {
    
        @Pointcut("execution(* com.my.*.*(..))")
        public void log(){}
    
        @Before("log()")
        public void before() {
            System.out.println("before do");
        }
    
        @Around("log()")
        public Object around(ProceedingJoinPoint pjp) throws Throwable {
            System.out.println("do 1");
            pjp.proceed();
            System.out.println(pjp.getSignature().getClass().getName() + "." +
                    pjp.getSignature().getName());
            System.out.println("do 2");
            return null;
        }
    }
    
    1. xml配置,开启AOP自动代理。
    <?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
            https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
    
        <bean id="userService" class="com.my.UserService" />
    
        <!-- 将切面注入。 -->
        <bean id="log" class="com.my.LogAspect"/>
        <!-- AOP使用注解实现时,需要开启自动代理的配置。-->
        <aop:aspectj-autoproxy/>
    </beans>
    
  4. Spring AOP,xml中配置不同的实现方式。

    1. proxy-target-class="false",Spring默认配置,使用JDK动态代理。
    2. proxy-target-class="true",使用cglib代理。
<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">

    <bean id="userService" class="com.my.UserService" />

    <bean id="log" class="com.my.LogAspect"/>
    <!--proxy-target-class="false" 默认,使用的是JDK动态代理。
     proxy-target-class="true" 使用cglib代理。-->
    <aop:aspectj-autoproxy proxy-target-class="false"/>
</beans>

6.Spring整合Mybatis,通过注入SqlSessionTemplate实现

  1. 需要导入的依赖。
<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.26</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.3.8</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>5.3.8</version>
    </dependency>
    <!-- AOP-->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.9.7</version>
    </dependency>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.7</version>
    </dependency>
    <!-- 整合包 -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>2.0.6</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13.1</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.20</version>
    </dependency>
</dependencies>
  1. mybatis配置文件。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <package name="com.my.dao.User"/>
    </typeAliases>
</configuration>
  1. Java类
@Data
public class User {

    private Integer id;
    private String name;
    private Integer age;
}
  1. mapper.xml文件。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.my.dao.UserDao">
    <select id="getAll" resultType="com.my.dao.User">
        select * from tb_user
    </select>
</mapper>
  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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/springboot"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- mybatis配置文件的位置 -->
        <property name="configLocation" value="mybatis-config.xml"/>
        <!-- mapper的位置 -->
        <property name="mapperLocations" value="classpath*:com/my/dao/*.xml"/>
    </bean>

    <bean id="template" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg ref="sqlSessionFactory"/>
    </bean>

    <bean id="userDao" class="com.my.dao.impl.UserDaoImpl">
        <property name="template" ref="template"/>
    </bean>
</beans>
  1. 测试类,通过注入SqlSessionTemplate来获取mapper对象。
public interface UserDao {

    List<User> getAll();
}

public class UserDaoImpl implements UserDao {

    private SqlSessionTemplate template;

    public void setTemplate(SqlSessionTemplate template) {
        this.template = template;
    }

    @Override
    public List<User> getAll() {
        UserDao userDao = template.getMapper(UserDao.class);
        return userDao.getAll();
    }
}
public class UserTest {

    @Test
    public void test01() {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        UserDao userDao = context.getBean("userDao", UserDao.class);
        List<User> users = userDao.getAll();
        users.forEach(System.out::print);
    }
}

7.Spring整合Mybatis,通过继承SqlSessionDaoSupport实现

  1. 继承SqlSessionDaoSupport来获取SqlSession。
public class UserDaoImpl2 extends SqlSessionDaoSupport implements UserDao {

    @Override
    public List<User> getAll() {
        UserDao userDao = getSqlSession().getMapper(UserDao.class);
        return userDao.getAll();
    }
}
  1. 继承SqlSessionDaoSupport的实现方式,需要注入sqlSessionFactory。
<?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="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/springboot"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- mybatis配置文件的位置 -->
        <property name="configLocation" value="mybatis-config.xml"/>
        <!-- mapper的位置 -->
        <property name="mapperLocations" value="classpath*:com/my/dao/*.xml"/>
    </bean>
    
    <!-- 继承SqlSessionDaoSupport的实现方式,需要注入sqlSessionFactory。 -->
    <bean id="userDao2" class="com.my.dao.impl.UserDaoImpl2">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
</beans>

8.Spring事务配置,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:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/springboot"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </bean>

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!-- mybatis配置文件的位置 -->
        <property name="configLocation" value="mybatis-config.xml"/>
        <!-- mapper的位置 -->
        <property name="mapperLocations" value="classpath*:com/my/dao/*.xml"/>
    </bean>

    <bean id="template" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg ref="sqlSessionFactory"/>
    </bean>

    <bean id="userDao" class="com.my.dao.impl.UserDaoImpl">
        <property name="template" ref="template"/>
    </bean>

    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>

    <aop:config>
        <!-- 切点 -->
        <aop:pointcut id="pointcut" expression="execution(* com.my.dao.impl.*.*(..))"/>
        <aop:advisor advice-ref="advice" pointcut-ref="pointcut"/>
    </aop:config>

    <tx:advice id="advice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="add" propagation="REQUIRED"/>
            <tx:method name="delete" propagation="REQUIRED"/>
            <tx:method name="update" propagation="REQUIRED"/>
            <tx:method name="query" read-only="true"/>
            <tx:method name="*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>
</beans>
posted @ 2021-07-31 21:26  行稳致远方  阅读(46)  评论(0)    收藏  举报