教育行業(yè)A股IPO第一股(股票代碼 003032)

全國(guó)咨詢/投訴熱線:400-618-4000

Spring中都應(yīng)用了哪些設(shè)計(jì)模式?

更新時(shí)間:2023年04月13日11時(shí)38分 來(lái)源:傳智教育 瀏覽次數(shù):

好口碑IT培訓(xùn)

  Spring框架是一個(gè)廣泛應(yīng)用于Java企業(yè)級(jí)應(yīng)用程序開(kāi)發(fā)的輕量級(jí)框架,它借鑒了許多設(shè)計(jì)模式來(lái)實(shí)現(xiàn)其各種功能。

  下面是Spring中常見(jiàn)的幾種設(shè)計(jì)模式及其應(yīng)用:

  1.單例模式

  Spring中的Bean默認(rèn)是單例模式,即只創(chuàng)建一個(gè)Bean實(shí)例并在整個(gè)應(yīng)用程序中共享它。這種方式可以提高性能和減少內(nèi)存占用。

  以下是一個(gè)簡(jiǎn)單的示例,展示如何在Spring中配置一個(gè)單例Bean:

<bean id="mySingletonBean" class="com.example.MySingletonBean" scope="singleton"/>

  2.工廠模式

  Spring使用工廠模式來(lái)管理對(duì)象的創(chuàng)建和生命周期。例如,Spring的ApplicationContext接口就是一個(gè)工廠,它可以創(chuàng)建和管理Bean實(shí)例。

  以下是一個(gè)示例,展示如何在Spring中配置一個(gè)工廠Bean:

<bean id="myFactoryBean" class="com.example.MyFactoryBean">
    <property name="someProperty" value="someValue"/>
</bean>

  3.代理模式

  Spring使用代理模式來(lái)實(shí)現(xiàn)AOP(面向切面編程),該模式允許在方法調(diào)用前、調(diào)用后或拋出異常時(shí)執(zhí)行某些額外的操作,如日志記錄、事務(wù)管理等。

  以下是一個(gè)示例,展示如何在Spring中配置一個(gè)代理Bean:

<bean id="myTargetBean" class="com.example.MyTargetBean"/>
<bean id="myAdvice" class="com.example.MyAdvice"/>
<bean id="myProxyBean" class="org.springframework.aop.framework.ProxyFactoryBean">
    <property name="target" ref="myTargetBean"/>
    <property name="interceptorNames">
        <list>
            <value>myAdvice</value>
        </list>
    </property>
</bean>

  4.觀察者模式

  Spring 中的事件機(jī)制使用了觀察者模式,它允許多個(gè)對(duì)象對(duì)某個(gè)事件進(jìn)行觀察,并在事件發(fā)生時(shí)自動(dòng)執(zhí)行相應(yīng)的操作。

  以下是一個(gè)示例,展示如何在 Spring 中使用事件機(jī)制:

public class MyEvent extends ApplicationEvent {
    public MyEvent(Object source) {
        super(source);
    }
}

public class MyListener implements ApplicationListener<MyEvent> {
    @Override
    public void onApplicationEvent(MyEvent event) {
        System.out.println("Received event: " + event);
    }
}

public class MyPublisher {
    private final ApplicationEventPublisher publisher;

    public MyPublisher(ApplicationEventPublisher publisher) {
        this.publisher = publisher;
    }

    public void publishEvent() {
        publisher.publishEvent(new MyEvent(this));
    }
}

@Configuration
public class AppConfig {
    @Bean
    public MyListener myListener() {
        return new MyListener();
    }

    @Bean
    public MyPublisher myPublisher(ApplicationEventPublisher publisher) {
        return new MyPublisher(publisher);
    }
}

  在這個(gè)示例中,MyEvent是一個(gè)自定義事件,MyListener是一個(gè)事件監(jiān)聽(tīng)器,MyPublisher是一個(gè)事件發(fā)布者。在AppConfig中,我們將MyListener和 MyPublisher注冊(cè)為Spring Bean,MyPublisher 構(gòu)造函數(shù)中注入了 ApplicationEventPublisher,它是一個(gè)接口,用于發(fā)布事件。在 MyPublisher 的 publishEvent 方法中,我們發(fā)布了一個(gè) MyEvent 事件,MyListener 將會(huì)監(jiān)聽(tīng)該事件并在事件發(fā)生時(shí)打印一條消息。

  5.模板方法模式

  Spring中的JdbcTemplate和HibernateTemplate 等模板類使用了模板方法模式,它允許將一些通用的代碼邏輯放在抽象父類中,而將具體的實(shí)現(xiàn)細(xì)節(jié)留給子類去實(shí)現(xiàn)。

  以下是一個(gè)簡(jiǎn)單的示例,展示如何在 Spring 中使用 JdbcTemplate:

public class MyDao {
    private final JdbcTemplate jdbcTemplate;

    public MyDao(JdbcTemplate jdbcTemplate) {
        this.jdbcTemplate = jdbcTemplate;
    }

    public List<MyObject> getMyObjects() {
        return jdbcTemplate.query("SELECT * FROM my_table", new MyObjectRowMapper());
    }

    private static class MyObjectRowMapper implements RowMapper<MyObject> {
        @Override
        public MyObject mapRow(ResultSet rs, int rowNum) throws SQLException {
            MyObject myObject = new MyObject();
            myObject.setId(rs.getLong("id"));
            myObject.setName(rs.getString("name"));
            return myObject;
        }
    }
}

@Configuration
public class AppConfig {
    @Bean
    public DataSource dataSource() {
        // configure and return a data source
    }

    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    @Bean
    public MyDao myDao(JdbcTemplate jdbcTemplate) {
        return new MyDao(jdbcTemplate);
    }
}

  在這個(gè)示例中,MyDao類使用了JdbcTemplate來(lái)查詢數(shù)據(jù)庫(kù)。JdbcTemplate提供了一組通用的查詢方法,例如query和update,可以直接執(zhí)行SQL語(yǔ)句并返回結(jié)果。在MyDao的getMyObjects方法中,我們使用了 JdbcTemplate的query方法來(lái)查詢my_table表中的數(shù)據(jù),并使用MyObjectRowMapper類將結(jié)果映射成MyObject對(duì)象。MyObjectRowMapper實(shí)現(xiàn)了RowMapper接口,它將ResultSet中的每一行數(shù)據(jù)映射成一個(gè)MyObject對(duì)象。

  在AppConfig中,我們配置了一個(gè)DataSource和一個(gè)JdbcTemplate,并將JdbcTemplate注入到 MyDao中。通過(guò)這種方式,我們可以將數(shù)據(jù)庫(kù)訪問(wèn)的通用邏輯放在JdbcTemplate中,而將具體的SQL語(yǔ)句和對(duì)象映射邏輯留給 MyDao類去實(shí)現(xiàn)。

0 分享到:
和我們?cè)诰€交談!