spring学习笔记2

1.Spring Bean的装配和注入。

        1.1 使用XML的方式创建Spring 上下文的方式实现bean的创建及注入。

            1. 显式的使用<bean> 标签,直接通过Class属性,设置需要注入bean的全限定名,可以将bean注入到Spring容器中。可以(可选)对对应的bean设置Id或者Neme,如果不设置id或name,将会自动创建默认的全限定名为Name的bean。例如注入了com.citrus.demo.UserService,将就可以通过applicationContext.getBean("com.citrus.demo.UserService")获取到bean。

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


        <bean name="userService" class="com.citrus.demo.service.UserServiceImpl">
        </bean>

        <bean name="userController" class="com.citrus.demo.controller.UserController">
            <constructor-arg name="userService" ref="userService"/>
        </bean>
</beans>

2.使用注解的方式。 

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


        <bean name="userService"  class="com.citrus.demo.service.UserServiceImpl">
        </bean>

        <bean  class="com.citrus.demo.controller.UserController">
            <constructor-arg name="userService" ref="userService"/>
        </bean>

    <context:component-scan base-package="com.citrus.demo"/>

    <aop:aspectj-autoproxy/>
    <context:annotation-config/>
</beans>

2.1 需要指定对应的包扫描路劲  <context:component-scan base-package="com.xx.xx"/>,Spring就会去扫描到指定的带有例如RestController、Component、Service……等注解的类,然后创建指定的Bean。

@RestController
public class UserController {
    private final IUserService userService;

    @Autowired
    public UserController(IUserService userService) {
        this.userService = userService;
    }


    public String findUserOne(){
        return userService.findUserOne("admin","123");
    }

}

 2.2 通过@Configuration注解配合@Bean注解实现注入。@Configuration等效于XML下的 <beans>标签,@Bean等效于<bean>,同样可以Bean的注入。

@Configuration
@ComponentScan("com.citrus.demo")
public class JdbcTemplateConfig {
    private final HikariDataSource hikariDataSource;

    @Autowired
    public JdbcTemplateConfig(HikariDataSource hikariDataSource) {
        this.hikariDataSource = hikariDataSource;
    }

    @Bean
    public JdbcTemplate configJdbc() {
        JdbcTemplate jdbcTemplate = new JdbcTemplate();
        jdbcTemplate.setDataSource(hikariDataSource);
        return jdbcTemplate;
    }
}

2.Spring Aop技术的使用与AspectJ原生的差异。

        1.使用原生的AspectJ实现Aop技术

           可以实现完整强大的Aop技术,使用略嫌麻烦,需要借助三方脚本,接触插件进行编译织入,也可以实现运行时织入,需要如下依赖包,在aspectj官网可以看到对应的教程。

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.9.7</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.7</version>
        </dependency>

2.使用Spring的Aop

        只需要 导入AspectJWear依赖和Spring-aop依赖支持即可。

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.7</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring-version}</version>
        </dependency>

        2.1 使用XML配置的方式使Aop生效。使用<aop: config>……等标签实现,可以实现前置通知、后置通知,环绕通知、抛出异常通知……等。

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

        <bean name="userService"  class="com.citrus.demo.service.UserServiceImpl">
        </bean>

        <bean  class="com.citrus.demo.controller.UserController">
            <constructor-arg name="userService" ref="userService"/>
        </bean>

    <context:component-scan base-package="com.citrus.demo"/>
    <bean name="aspectDemo" class="com.citrus.demo.advice.AspectDemo"/>
    <aop:config>
        <aop:aspect ref="aspectDemo">
            <aop:around method="around"
                                
              pointcut="@annotation(com.citrus.demo.advice.anno.TestAdviceAnnotation))"
            />
            <aop:after method="after"
                        pointcut="execution(* com.citrus.demo.service.*.*(..))"
            />
            <aop:before method="before"
                       pointcut="execution(* com.citrus.demo.service.*.*(..))"
            />
        </aop:aspect>
    </aop:config>

    <context:annotation-config/>
</beans>

       增强类:

   

@Aspect
public class AspectDemo {

    public void before() {
        System.out.println("前置通知执行!!!");
    }

    public void after() {
        System.out.println("后置通知执行!!!");
    }

    public String around(ProceedingJoinPoint joinPoint) {
        String result = "";
        System.out.println("环绕通知 执行!!");
        try {
            Object[] args = joinPoint.getArgs();
            for (Object o : args) {
                System.out.println("参数有:" + (String) o);
            }
            result = (String) joinPoint.proceed();
            System.out.println("返回值是" + result);
        } catch (Throwable e) {
            e.printStackTrace();
            result = "发生未知的错误: " + e.getMessage();
        }
        return result;
    }
}

 2.2 使注解的方式使Aop生效。注解是同@Aspect和Component注解,并在Spring ApplicationContext上下文中配置使用<aop:aspectj-autoproxy/>开启自动扫描Aspect类即可。还需要开启组件扫描<context:component-scan base-package="com.citrus.demo"/>

       applicationContext.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: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/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        ">
        <bean name="userService"  class="com.citrus.demo.service.UserServiceImpl">
        </bean>
        <bean  class="com.citrus.demo.controller.UserController">
            <constructor-arg name="userService" ref="userService"/>
        </bean>
    <context:component-scan base-package="com.citrus.demo"/>
    <bean name="aspectDemo" class="com.citrus.demo.advice.AspectDemo"/>
    <aop:aspectj-autoproxy/>
    <context:annotation-config/>
</beans>

Aspect类: 

@Aspect
@Component
public class AspectDemo {

    @Before(value = "execution(* com.citrus.demo.service.*.*(..))")
    public void before() {
        System.out.println("前置通知执行!!!");
    }

    @After(value = "@annotation(com.citrus.demo.advice.anno.TestAdviceAnnotation)")
    public void after() {
        System.out.println("后置通知执行!!!");
    }

    @Around(value = "@annotation(com.citrus.demo.advice.anno.TestAdviceAnnotation)")
    public String around(ProceedingJoinPoint joinPoint) {
        String result = "";
        System.out.println("环绕通知 执行!!");
        try {
            Object[] args = joinPoint.getArgs();
            for (Object o : args) {
                System.out.println("参数有:" + (String) o);
            }
            result = (String) joinPoint.proceed();
            System.out.println("返回值是" + result);
        } catch (Throwable e) {
            e.printStackTrace();
            result = "发生未知的错误: " + e.getMessage();
        }
        return result;
    }
}

 其中Around环绕通知是常用的增强手段,它提供了强大的方法增强的支持。可以通过ProceedingJoinPoint 对增强的方法实现丰富的操作,可以通过joinPoint.getArgs()拿到增强方法的形参及其传递的参数,其中Around通知返回的参数,就是原方法的返回值,需要使用joinPoint.proceed()执行原方法后得到返回值显式的返回。包含对于方法执行的异常处理,Catch Throwable的顶层异常,对于异常可以进行统一的处理,方便维护管理。

对于Aop在开发中可以极大的提高代码的可维护性,可以实现一些十分强大的功能,常用的有:使用Aop实现日志的记录打印,为一些接口增加缓存,拦截认证等……可以极大地简化一些公共重复的代码的工作,使一些公共的行为可以进行统一的管理,例如200个接口需要记录日志,直接在接口上添加,效率很低,降低代码阅读性,后期难以维护,需要升级的时候需要手动更改每一个接口的代码。使用Aop以后,通过PointCut指定的表达式,可以对某一类方法实现增强,对标有某个注解的方法实现增强,对于某个包路径下的方法实现增强。后期维护只需要更改增强方法即可,极大提升了维护能力。

3.Spring 事务控制。

        1.在Servlet中需要进行事务控制。

                使用session.setAutoCommmit(false),session.commit,session.rollback可以简单的对jdbc事务进行控制,需要显式的在方法末尾进行commit操作,需要显式的在catch exception中对事务进行回滚。

                

    @Override
    public List<ServiceCategory> findCategoryList() {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        List<ServiceCategory> serviceCategories = new ArrayList<>();
        try {
            connection = HikariCpUtils.getHikariConnection();
            connection.setAutoCommit(false);
            preparedStatement = connection.prepareStatement("select * from service_category");
            resultSet = preparedStatement.executeQuery();
            ServiceCategory serviceCategory = null;
            while (resultSet.next()) {
                serviceCategory = new ServiceCategory();
                serviceCategory.setId(resultSet.getLong(1));
                serviceCategory.setName(resultSet.getString(2));
                serviceCategory.setInfo(resultSet.getString(3));
                serviceCategory.setLink(resultSet.getString(4));
                serviceCategory.setState(resultSet.getInt(5));
                serviceCategory.setCreateUser(resultSet.getString(6));
                serviceCategory.setModifiedUser(resultSet.getString(7));
                serviceCategory.setCreateTime(resultSet.getTimestamp(8).toLocalDateTime());
                serviceCategory.setModifiedTime(resultSet.getTimestamp(9).toLocalDateTime());
                serviceCategories.add(serviceCategory);
            }
        } catch (SQLException e) {
            try {
                if (connection != null) {
                    connection.rollback();
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            try {
                if (connection != null) {
                    connection.commit();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            HikariCpUtils.closeConnection(connection, preparedStatement, resultSet);
        }
        return serviceCategories;
    }

在spring中,提供了对于事务的支持与管理。PlatformTransactionManager 接口是 spring 的事务管理器,提供了常用的操作事务的方法……未完待续

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值