Spring小记

本文详细介绍了如何在Spring中使用XML配置和注解方式实现自动装配,以及如何通过AOP进行事务管理,重点展示了如何在IOC容器中注入复杂类型和多个接口实现类,并结合JdbcTemplate进行数据库操作。
摘要由CSDN通过智能技术生成

从IOC容器获取bean

ClassPathXmlApplicationContext(从类路径获取文件) 和 FileSystemXmlApplicationContext(从系统磁盘径获取文件)。

方式一(ClassPathXmlApplicationContext(从类路径获取文件)方式):
实体类:

public class Person {
    private String name;
    private Integer age;
    
    public Person() {
        super();
        System.out.println("构造方法被调用");
    }
        //getters、setters、toString
}

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"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
      
    <!-- bean:使容器创建Person的对象 -->
    <!-- name:相当于变量名 Person p = new Person(); -->
    <!-- class:类的全限定名 -->     
    <bean name="p" class="com.qfedu.spring.pojo.Person"></bean>   
</beans>

获取bean测试:

public class IOCTest {
    @Test
    public void testCreatePerson() {
        
        //创建容器
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //查找对象
        Person p = (Person)context.getBean("p");
        System.out.println(p);
    }
}

方式二(FileSystemXmlApplicationContext(从系统磁盘径获取文件)方式):

 @Test
    public void ApplicationContext() {    
        //创建容器
        ApplicationContext context = new FileSystemXmlApplicationContext("D:\\workspace_helen\\web-gp1701\\spring-01-hello\\src\\applicationContext.xml");
    }

复杂类型注入

    private Object[] cars;//数组类型的注入
    private List friends; //list类型的注入
    private Set set;//set类型的注入
    private Map map;//map类型的注入
    private Properties properties;//properties类型的注入
<bean name="person5" class="com.qfedu.spring.pojo.Person">
        <property name="name" value="houkunpeng"></property>
        <property name="age" value="16"></property>
        <property name="car" ref="car"></property>
        <property name="cars">
            <array>
                <value>自行车</value>
                <value>手扶拖拉机</value>
                <ref bean="car" />
            </array>
        </property>
        <property name="friends">
            <list>
                <value>洋妞红</value>
                <value>溜冰摔</value>
                <value>少元彬</value>
            </list>
        </property>
        <property name="set">
            <set>
                <value>set3</value>
                <value>set2</value>
                <value>set1</value>
            </set>
        </property>
        <property name="map">
            <map>
                <entry key="username" value="root"></entry>
                <entry key="car" value-ref="car"></entry>
                <entry key-ref="person1" value-ref="car"></entry>
            </map>
        </property>
        <property name="properties">
            <props>
                <prop key="username">root</prop>
                <prop key="password">123456</prop>
            </props>
        </property>
        
    </bean>

一个接口有多个实现类,如何自动装配

自动装配存在的问题:如果一个类型有多个对象(一个接口有多个实现类),那么可以采用以下的方式:
TestService接口:

public interface TestService {
    public void getMessage();
}

TestServiceImpl实现TestService:

@Service
public  class TestServiceImpl implements TestService {

    @Override
    public void getMessage() {
        System.out.println("test serviceImpl one");
    }
}

TestServiceImpl2实现TestService:

@Service
public class TestServiceImpl2 implements TestService {
    @Override
    public void getMessage() {
        System.out.println("test serviceImpl tow");
    }
}

测试类:
解决装配起义性的方式有三种

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
class TestServiceImplTest {

    // 方式一
//    @Autowired // 按照byType自动装配
//    @Qualifier("testServiceImpl") // 按照byName,类名首字母小写

    // 方式二
 //   @Resource(type = com.xmm.springboot_lab.service.impl.TestServiceImpl.class)// 按照byType
    // 方式三
    @Resource(name = "testServiceImpl2") //按照byName,类名首字母小写
    private TestService testService;

    @Test
    void getMessage() {
        testService.getMessage();
    }
}

AOP

aop和代理:blog.csdn.net/qq_41701956/article/details/84427891

AOP是能够让我们在不影响原有功能的前提下,为软件横向扩展功能。

方式一
aop通过xml方式:

public class UserServiceImpl implements UserService{
    @Override
    public void save() {
        System.out.println("保存用户");
    }
    @Override
    public void delete() {
        System.out.println("删除用户");
    }
    @Override
    public void update() {
        System.out.println("更新用户");
    }
    @Override
    public void select() {
        System.out.println("查询用户");
    }
}

切面类:

public class TransactionAdvice {
//    前置通知:在目标方法之前调用
//    后置通知(如果出现异常就不调用):在目标方法之后调用
//    返回通知(无论是否出现异常都会调用):在目标方法之后调用
//    环绕通知:在目标方法之前、后调用
//    异常通知:出现异常则调用
    
    public void before() {
        System.out.println("前置通知被执行");
    }
    
    public void afterReturning() {
        System.out.println("后置通知被执行(出现异常不调用)");
    }
    
    public void after() {
        System.out.println("后置通知被执行(无论是否出现异常都会调用)");
    }
    
    public void afterException() {
        System.out.println("异常通知被执行");
    }
    
    public Object around(ProceedingJoinPoint point) throws Throwable {
        System.out.println("");
        Object proceed = point.proceed();//调用目标方法
        System.out.println("");
        return proceed;
    }
}

xml配置:

<!-- 目标对象 -->   
    <bean name="userService" class="com.qfedu.spring.aop.service.UserServiceImpl"></bean>
    
    <!-- 通知对象 -->
    <bean name="transactionAdvice" class="com.qfedu.spring.aop.advice.TransactionAdvice"></bean>
    <!-- 将通知对象织入目标对象 -->
    <aop:config>
        <!-- 选择切入点 -->
        <aop:pointcut expression="execution(* com.qfedu.spring.aop.service..*ServiceImpl.*(..))" id="pointcut"/>
        <aop:aspect ref="transactionAdvice">
            <aop:before method="before" pointcut-ref="pointcut"/>
            <aop:after-returning method="afterReturning" pointcut-ref="pointcut"/>
            <aop:after method="after" pointcut-ref="pointcut"/><!-- 无论是否出现异常都会调用 -->
            <aop:around method="around" pointcut-ref="pointcut"/>
            <aop:after-throwing method="afterException" pointcut-ref="pointcut"/>
        </aop:aspect>
    </aop:config>

测试:

//创建容器
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
    @Resource(name="userService")
    private UserService userService;
    
    @Test
    public void testSave() {
        userService.save("helen");
    }  
    @Test
    public void testUpdate() {
        userService.update();
    }
}

方式二
aop通过注解方式:

public class UserServiceImpl implements UserService{
    @Override
    public void save() {
        System.out.println("保存用户");
    }
    @Override
    public void delete() {
        System.out.println("删除用户");
    }
    @Override
    public void update() {
        System.out.println("更新用户");
    }
    @Override
    public void select() {
        System.out.println("查询用户");
    }
}

切面类:

@Aspect
public class TransactionAdvice {
    @Pointcut("execution (* com.qfedu.spring.aop.service..*ServiceImpl.*(..))")
    private void anyMethod() {} // 声明一个切入点,anyMethod为切入点名称
    
     // 声明该方法是一个前置通知:在目标方法开始之前执行 
    @Before("anyMethod()")
    public void doAccessCheck() {
          System.out.println("前置通知被执行");
    }
}

xml配置:

 <!-- 目标对象 -->   
    <bean name="userService" class="com.qfedu.spring.aop.service.UserServiceImpl"></bean>
    
    <!-- 通知对象 -->
    <bean name="transactionAdvice" class="com.qfedu.spring.aop.advice.TransactionAdvice"></bean>
    <!-- 开启织入注解 -->
   <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

测试:

/创建容器
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AopTest {
    @Resource(name="userService")
    private UserService userService;
    
    @Test
    public void testSave() {
        userService.save("helen");
    }
    
    @Test
    public void testUpdate() {
        userService.update();
    }
}

Jdbc Tempalte

实体类:

public class Role {
    private Integer rid;
    private String rname;
    private String alias;
    //空参构造、getters、setters
    @Override
    public String toString() {
        return "Role [rid=" + rid + ", rname=" + rname + ", alias=" + alias + "]";
    }
}

dao接口:

package com.qfedu.spring.dao;
public interface RoleDao {
    void save(Role role);
    
    void delete(Integer id);
    
    void update(Role role);
    
    Role getById(Integer id);
    
    List<Role> getAll();
    
    int getTotalCount();
}

实现dao接口:

package com.qfedu.spring.dao;
public class RoleDaoImpl implements RoleDao{
    JdbcTemplate jt;
    public void setJt(JdbcTemplate jt) {
        this.jt = jt;
    }
    @Override
    public void save(Role role) {
        String sql = " INSERT INTO ar_role ( "
                + " rname,"
                + " alias"
                + " ) VALUES (?,?)" ;
        jt.update(sql, role.getRname(), role.getAlias());
    }
    @Override
    public void delete(Integer id) {
        String sql = " delete from ar_role where rid = ?" ;
        jt.update(sql, id);
    }
    @Override
    public void update(Role role) {
        String sql = " update ar_role set rname = ?, alias = ? where id = ?";
        jt.update(sql, role.getRname(), role.getAlias(), role.getRid());
    }
    @Override
    public Role getById(Integer id) {
        String sql = "select * from ar_role where rid = ?";
        Role role = jt.queryForObject(sql, new RowMapper<Role>() {
            @Override
            public Role mapRow(ResultSet rs, int index) throws SQLException {
                return maoRowHandler(rs);
            }
        }, id);
        return role;
    }
    @Override
    public List<Role> getAll() {
        String sql = "select * from ar_role";
        List<Role> list = jt.query(sql, new RowMapper<Role>() {
            @Override
            public Role mapRow(ResultSet rs, int index) throws SQLException {
                return maoRowHandler(rs);
            }
        });
        return list;
    }
    @Override
    public int getTotalCount() {
        String sql = "select count(1) from ar_role";
        Integer count = jt.queryForObject(sql, Integer.class);
        return count;
    }
    
    private Role maoRowHandler(ResultSet rs) throws SQLException {
        Role role = new Role();
        role.setRname(rs.getString("rname"));
        role.setAlias(rs.getString("alias"));
        role.setRid(rs.getInt("rid"));
        return role;
    }
}

创建db.properties:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/spring-gp1701
jdbc.username=root
jdbc.password=123456

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"
    xmlns:aop="http://www.springframework.org/schema/aop"
    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
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop.xsd">
        
<context:property-placeholder location="classpath:db.properties" />        
<!-- 连接池 -->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="${jdbc.driver}"></property>
    <property name="jdbcUrl" value="${jdbc.url}"></property>
    <property name="user" value="${jdbc.username}"></property>
    <property name="password" value="${jdbc.password}"></property>
</bean>
<!-- JdbcTemplate -->
<bean name="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <property name="dataSource" ref="dataSource"></property>
</bean>
<!-- roleDao -->
<bean name="roleDao" class="com.qfedu.spring.dao.RoleDaoImpl">
    <property name="jt" ref="jdbcTemplate"></property>
</bean>
</beans>

测试:

package com.qfedu.spring.jdbctemplate;
//创建容器
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestSpringJdbcTemplate {
    
    @Resource(name="roleDao")
    private RoleDao roleDao;
    
    @Test
    public void testSave(){
        
        Role role = new Role();
        role.setRname("spring1");
        role.setAlias("spring11");
        roleDao.save(role);
    }
    
    @Test
    public void testDelete(){
        
        roleDao.delete(5);
    }
    
    @Test
    public void testUpdate(){
        Role role = new Role();
        role.setRname("spring4");
        role.setAlias("spring44");
        role.setRid(4);
        roleDao.update(role);
    }
    
    @Test
    public void testGetById(){
        Role role = roleDao.getById(4);
        System.out.println(role);
    }
    
    @Test
    public void testGetAll(){
        List<Role> roleList = roleDao.getAll();
        System.out.println(roleList);
    }
    
    @Test
    public void testGetTotalCount(){
        Integer count = roleDao.getTotalCount();
        System.out.println(count);
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值